Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScriptでテストコードを徹底的に型推論する / TypeScript Meetup 4
Search
OKUNOKENTARO
June 16, 2020
Technology
8
3.5k
TypeScriptでテストコードを徹底的に型推論する / TypeScript Meetup 4
2020年6月16日 TypeScript Meetup #4 にて発表した資料です。
OKUNOKENTARO
June 16, 2020
Tweet
Share
More Decks by OKUNOKENTARO
See All by OKUNOKENTARO
トレタO/X アーキテクチャ移行記 Next.js App Router化への道のり / TORETA TECH UPDATE 1
okunokentaro
5
11k
Podcastを継続する技術 / refactoradio-240119
okunokentaro
1
170
Webアプリケーション設計の第一歩は ディレクトリの整理から / Encraft 1
okunokentaro
34
10k
JSONとJSON Schemaを改めて理解する / tokyo_study
okunokentaro
9
2.3k
それでもどうしてRecoilを使うのか / Harajuku.ts Meetup Recoil
okunokentaro
19
5.5k
TypeScriptは10年でこんなに進化しました / TechFeed Experts Night 11
okunokentaro
6
1.7k
Hasura.io RDBをサクサク作る方法はARやO/RMだけじゃなくなりました/hasura-io
okunokentaro
5
650
コードには型アノテーションよりも要件アノテーションを増やせ!/harajukuts2
okunokentaro
14
6.3k
10年と3ヶ月でWebサービスを作った話 / Piyogrammer Conference 2021
okunokentaro
2
1k
Other Decks in Technology
See All in Technology
LINE Notify互換のボットを作った話
kenichirokimura
0
180
バックエンドエンジニアによるフロントエンドテスト拡充の具体的手法
kinosuke01
1
710
BCMathを高速化した一部始終をC言語でガチ目に解説する / BCMath performance improvement explanation
sakitakamachi
2
1.2k
Dapr For Java Developers SouJava 25
salaboy
1
130
問題解決に役立つ数理工学
recruitengineers
PRO
7
2.1k
AI・LLM事業部のSREとタスクの自動運転
shinyorke
PRO
0
300
Riverpod & Riverpod Generatorを利用して状態管理部分の処理を書き換えてみる簡単な事例紹介
fumiyasac0921
0
110
ソフトウェア開発におけるインターフェイスという考え方 / PHPerKaigi 2025
k1low
9
3.9k
ISUCONにPHPで挑み続けてできるようになっ(てき)たこと / phperkaigi2025
blue_goheimochi
0
140
職種に名前が付く、ということ/The fact that a job title has a name
bitkey
1
240
Cloud Native PG 使ってみて気づいたことと最新機能の紹介 - 第52回PostgreSQLアンカンファレンス
seinoyu
2
200
大規模アジャイル開発のリアル!コミュニケーション×進捗管理×高品質
findy_eventslides
0
520
Featured
See All Featured
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Large-scale JavaScript Application Architecture
addyosmani
511
110k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Navigating Team Friction
lara
184
15k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
135
33k
The Cost Of JavaScript in 2023
addyosmani
48
7.6k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Why Our Code Smells
bkeepers
PRO
336
57k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
12
1.4k
Product Roadmaps are Hard
iamctodd
PRO
52
11k
Docker and Python
trallard
44
3.3k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
30
2.3k
Transcript
5ZQF4DSJQUͰ ςε τίʔ υΛపఈతʹܕਪ͢Δ +VO 5ZQF4DSJQU.FFUVQ !PLVOPLFOUBSP
୭ w Ԟݡଠ!PLVOPLFOUBSP w 5ZQF4DSJQUϑϩϯ τΤϯ υ ɾ όοΫΤϯ υ
w "OHVMBSຊϢʔβʔձ w OHKBQBO0O"JSύʔιφϦςΟ
ςε τίʔ υ BOZͰఘΊ͍ͯ·ͤΜ͔
ྫ͑ describe('TasksService', () => { let spy: any; beforeEach(() =>
{ // 略 spy = jest.spyOn(tasksService, 'fetchTasks'); }); test('テスト', () => { // 略 }); });
describe('TasksService', () => { let spy: any; beforeEach(() => {
// 略 spy = jest.spyOn(tasksService, 'fetchTasks'); }); test('テスト', () => { // 略 }); }); ྫ͑
describe('TasksService', () => { let spy: any; beforeEach(() => {
// 略 spy = jest.spyOn(tasksService, 'fetchTasks'); }); test('テスト', () => { // 略 }); }); ྫ͑
ͳͥBOZʹͯ͠͠· ͏ͷ͔ w ܕఆٛΛ͍͍͚ͨͲɺ .d.tsΛಡΜͰҙຯ͕͔Βͳ͔ͬͨ w γϯϓϧͳܕఆٛ͡Όͳ͘ ͯδΣωϦΫεͷࢦఆ͕ඞཁ w ͦ͜ʹԿΛࢦఆͨ͠Β͍͍͔͔Βͣɺ
͍ͭ·ͰίϯύΠϧΤϥʔʹͳΔ w ఘΊͯanyʹ͓ͯ͘͠
KFTUTQZ0Oͷܕఆٛ https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L273-L294
None
ͲΕΛ͍͍͑ͷ ʁ Ͳͬͪ ʁ ʁ ͜ͷ͍ͷԿ ʁ ʁ
ͭ͋Δͷ0WFSMPBET https://www.typescriptlang.org/docs/handbook/functions.html#overloads ্͔ΒॱʹධՁ ͯ͠߹கͨ͠ͷ͕ ΘΕΔ
5ԿΒ͔ͷΦϒδΣΫ τ ٸʹ\^ͬͯॻ͔ΕΔͱ ͼͬ͘ Γ͢Δ͚Ͳɺ ͨͩͷ ۭ0CKFDU-JUFSBM VOEFpOFE OVMMҎ֎ͷ ͍ͣΕ\^Λຬͨ͢
.͕ॏཁ
ͱ Γ͋͑ͣԿΒ͔ͷจࣈྻͩ https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324
.BQQFE5ZQFT $POEJUJPOBM5ZQFT https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324 ࠓͲ͖ͷͷڽΒ͞Εͨ5ZQF4DSJQUܕఆٛ άάΓʹ͍͘ߏจ͕ͨ͘ ͞Μ ͍Ζ͍Ζग़͖ͯͯϫέΘ͔ΒΜ͔͠Εͳ͍͚Ͳ ͻͱͭͣͭղܾ͍ͯ͜͠͏ .BQQFE5ZQFT $POEJUJPOBM5ZQFT
-PPLVQ5ZQFT ͜Ε"SSBZBOZͷTVHBS
.BQQFE5ZQFT https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324 5͕࣋ͭશͯͷϓϩύςΟ Λʜ Α Γӈʹهड़͞Εͨܕʹ͢Δ
$POEJUJPOBM5ZQFT https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324 ͦͷܕ͕ࢦఆͷ݅Λʜ ຬͨ͢ͳΒ ຬͨ͞ͳ͍ͳΒҎ߱ ͷܕͱͳΔ
͏ҰಡΜͰΈΔͱ ୈҾ͕ʜ ΦϒδΣΫ τ5ͷ࣋ͭ ϓϩύςΟ໊ͳΒ ୈҾ͕HFU͔TFU͔ʹԠͯ͡ৼΓ͚ ΦϒδΣΫ τ5ͷ࣋ͭ ϝ ιο
υ໊ͳΒͭΊͷ0WFSMPBETΛద༻ ͭ· Γωε τͨ͠JGจͷΑ ͏ʹಡΊΔ
Ͳͷ0WFSMPBET͔͔ΕͦͷΓܕΛݟΔ ୈҾʹΠϯελϯεɺ ୈҾʹͦͷΠϯελϯε͕࣋ͭϝ ιο υ໊ ΛͤSpyInstance<T, Y>͕ฦΔ ͰReturnType ArgsTypeͱ
ʁ ʁ
Ϗϧ τΠϯͷ$POEJUJPOBM5ZQFT w lib.d.tsʹ5ZQF4DSJQUʹඪ४ͰΈࠐ·Ε͍ͯΔ $POEJUJPOBM5ZQFT͕ଘࡏ͢Δ w ReturnType<T>ͦͷͻͱͭ wʮstringΛฦؔ͢ʯ ΛTʹͤɺ ReturnType<T>stringͱͳΔ
ࣗ࡞ͷ$POEJUJPOBM5ZQFT w +FTUͷܕఆٛͰArgsType<T>ͱ͍͏ܕ͕ಠࣗʹఆٛ͞Ε͍ͯΔ w w ͠T͕extendsҎ߱ͷܕͱϚονͨ͠Βɺ ͦͷ࣌ͷҾܕAΛฦ͢ͱ͍͏ҙ ʢϚον͠ͳ͚ΕneverΛฦ͢ʣ
w inferΛͬͯ݅ʹϚονͨ͠ͱ͖ͷ֘ՕॴΛɺ ΓܕଆͰѻ͑Δ type ArgsType<T> = T extends (...args: infer A) => any ? A : never;
"OHVMBSͷ5FTU#FEʹ ຊؾͰܕΛ͚ͯΈΔ
ઈରʹܕ͚ΛఘΊͳ͍ w "OHVMBS%*ίϯςφΛඋ͑Δ w ςε τ࣮ࢪ࣌ʹಛఆͷαʔϏεΛϞοΫʹࠩ͠ସ࣮͑ͯߦͰ͖Δ w ΦϑΟ γϟϧͷܕఆ͍͍ٛͩͨanyͱॻ͔ΕͯΔ w
ώϡʔϚϯΤϥʔ͕ى͖͍͢ w anyͷ··ͰఘΊͳ͍
%FQFOEFODJFT5ܕ import { Type } from '@angular/core'; type MapToConstructorType<T extends
any[]> = { [P in keyof T]: Type<T[P]> }; export type Dependencies< T extends new (...args: any) => any > = MapToConstructorType<ConstructorParameters<T>>; w Router, TranslateService, UsersServiceΛ%*͢Δ MyComponent͕͋ͬͨͱ͢Δ w Dependencies<typeof MyComponent> [typeof Router, typeof TranslateService, typeof UsersService]ͱͷޓܕฦ͢
·ͱΊ w ࠷ۙͷϞμϯͳܕఆٛϑΝΠϧɺ ͻͨ͢Β܁Γฦ͠ͱ݅ذ w .BQQFE5ZQFT $POEJUJPOBM5ZQFTΛۦͯ͠ઈରʹܕ͚͍ͯ͜͠͏