Pro Yearly is on sale from $80 to $50! »

TypeScriptでテストコードを徹底的に型推論する / TypeScript Meetup 4

TypeScriptでテストコードを徹底的に型推論する / TypeScript Meetup 4

2020年6月16日 TypeScript Meetup #4 にて発表した資料です。

2bedb1eb8f841cd3c3ae584600b016e0?s=128

OKUNOKENTARO

June 16, 2020
Tweet

Transcript

  1. 5ZQF4DSJQUͰ ςε τίʔ υΛపఈతʹܕਪ࿦͢Δ +VO 5ZQF4DSJQU.FFUVQ !PLVOPLFOUBSP

  2. ୭ w Ԟ໺ݡଠ࿠!PLVOPLFOUBSP w 5ZQF4DSJQUϑϩϯ τΤϯ υ ɾ όοΫΤϯ υ

    w "OHVMBS೔ຊϢʔβʔձ w OHKBQBO0O"JSύʔιφϦςΟ
  3. ςε τίʔ υ BOZͰఘΊ͍ͯ·ͤΜ͔

  4. ྫ͑͹ describe('TasksService', () => { let spy: any; beforeEach(() =>

    { // 略 spy = jest.spyOn(tasksService, 'fetchTasks'); }); test('テスト', () => { // 略 }); });
  5. describe('TasksService', () => { let spy: any; beforeEach(() => {

    // 略 spy = jest.spyOn(tasksService, 'fetchTasks'); }); test('テスト', () => { // 略 }); }); ྫ͑͹
  6. describe('TasksService', () => { let spy: any; beforeEach(() => {

    // 略 spy = jest.spyOn(tasksService, 'fetchTasks'); }); test('テスト', () => { // 略 }); }); ྫ͑͹
  7. ͳͥBOZʹͯ͠͠· ͏ͷ͔ w ܕఆٛΛ࢖͍͍͚ͨͲɺ .d.tsΛಡΜͰ΋ҙຯ͕෼͔Βͳ͔ͬͨ w γϯϓϧͳܕఆٛ͡Όͳ͘ ͯδΣωϦΫεͷࢦఆ͕ඞཁ w ͦ͜ʹԿΛࢦఆͨ͠Β͍͍͔෼͔Βͣɺ

    ͍ͭ·Ͱ΋ίϯύΠϧΤϥʔʹͳΔ w ఘΊͯanyʹ͓ͯ͘͠
  8. KFTUTQZ0Oͷܕఆٛ https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L273-L294

  9. None
  10. ͲΕΛ࢖͑͹͍͍ͷ ʁ Ͳͬͪ ʁ ʁ ͜ͷ௕͍ͷ͸Կ ʁ ʁ

  11. ͭ͋Δͷ͸0WFSMPBET https://www.typescriptlang.org/docs/handbook/functions.html#overloads ্͔ΒॱʹධՁ ͯ͠߹கͨ͠΋ͷ͕ ࢖ΘΕΔ

  12. 5͸ԿΒ͔ͷΦϒδΣΫ τ ٸʹ\^ͬͯॻ͔ΕΔͱ ͼͬ͘ Γ͢Δ͚Ͳɺ ͨͩͷ ۭ0CKFDU-JUFSBM VOEFpOFE OVMMҎ֎ͷ஋͸ ͍ͣΕ΋\^Λຬͨ͢

  13. .͕ॏཁ

  14. ͱ Γ͋͑ͣԿΒ͔ͷจࣈྻͩ https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324

  15. .BQQFE5ZQFT $POEJUJPOBM5ZQFT https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324 ࠓͲ͖ͷ޻෉ͷڽΒ͞Εͨ5ZQF4DSJQUܕఆٛ͸ άάΓʹ͍͘ߏจ͕ͨ͘ ͞Μ ͍Ζ͍Ζग़͖ͯͯϫέΘ͔ΒΜ͔΋͠Εͳ͍͚Ͳ ͻͱͭͣͭղܾ͍ͯ͜͠͏ .BQQFE5ZQFT $POEJUJPOBM5ZQFT

    -PPLVQ5ZQFT ͜Ε͸"SSBZBOZͷTVHBS
  16. .BQQFE5ZQFT https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324 5͕࣋ͭશͯͷϓϩύςΟ Λʜ Α Γӈʹهड़͞Εͨܕʹ͢Δ

  17. $POEJUJPOBM5ZQFT https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f9f8e5ac0f73721b8ec393767a8caeffe93beeb1/types/jest/index.d.ts#L319-L324 ͦͷܕ͕ࢦఆͷ৚݅Λʜ ຬͨ͢ͳΒ  ຬͨ͞ͳ͍ͳΒҎ߱ ͷܕͱͳΔ

  18. ΋͏Ұ౓ಡΜͰΈΔͱ ୈҾ਺͕ʜ ΦϒδΣΫ τ5ͷ࣋ͭ ϓϩύςΟ໊ͳΒ͹ ୈҾ਺͕HFU͔TFU͔ʹԠͯ͡ৼΓ෼͚ ΦϒδΣΫ τ5ͷ࣋ͭ ϝ ιο

    υ໊ͳΒ͹ͭΊͷ0WFSMPBETΛద༻ ͭ· Γωε τͨ͠JGจͷΑ ͏ʹಡΊΔ
  19. Ͳͷ0WFSMPBET͔෼͔Ε͹ͦͷ໭ΓܕΛݟΔ ୈҾ਺ʹΠϯελϯεɺ  ୈҾ਺ʹͦͷΠϯελϯε͕࣋ͭϝ ιο υ໊ Λ౉ͤ͹SpyInstance<T, Y>͕ฦΔ Ͱ͸ReturnType ArgsTypeͱ͸

    ʁ ʁ
  20. Ϗϧ τΠϯͷ$POEJUJPOBM5ZQFT w lib.d.tsʹ͸5ZQF4DSJQUʹඪ४Ͱ૊Έࠐ·Ε͍ͯΔ $POEJUJPOBM5ZQFT͕ଘࡏ͢Δ w ReturnType<T>΋ͦͷͻͱͭ wʮstringΛฦؔ͢਺ʯ ΛTʹ౉ͤ͹ɺ ReturnType<T>͸stringͱͳΔ

  21. ࣗ࡞ͷ$POEJUJPOBM5ZQFT w +FTUͷܕఆٛͰ͸ArgsType<T>ͱ͍͏ܕ͕ಠࣗʹఆٛ͞Ε͍ͯΔ w  w ΋͠T͕extendsҎ߱ͷܕͱϚονͨ͠Βɺ ͦͷ࣌ͷҾ਺ܕAΛฦ͢ͱ͍͏ҙ ʢϚον͠ͳ͚Ε͹neverΛฦ͢ʣ 

    w inferΛ࢖ͬͯ৚݅ʹϚονͨ͠ͱ͖ͷ֘౰ՕॴΛɺ ໭ΓܕଆͰѻ͑Δ type ArgsType<T> = T extends (...args: infer A) => any ? A : never;
  22. "OHVMBSͷ5FTU#FEʹ ຊؾͰܕΛ෇͚ͯΈΔ

  23. ઈରʹܕ෇͚ΛఘΊͳ͍ w "OHVMBS͸%*ίϯςφΛඋ͑Δ w ςε τ࣮ࢪ࣌ʹಛఆͷαʔϏεΛϞοΫʹࠩ͠ସ࣮͑ͯߦͰ͖Δ w ΦϑΟ γϟϧͷܕఆٛ͸͍͍ͩͨanyͱॻ͔ΕͯΔ w

    ώϡʔϚϯΤϥʔ͕ى͖΍͍͢ w anyͷ··ͰఘΊͳ͍
  24. %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]ͱͷޓ׵ܕฦ͢
  25. ·ͱΊ w ࠷ۙͷϞμϯͳܕఆٛϑΝΠϧ͸ɺ ͻͨ͢Β܁Γฦ͠ͱ৚݅෼ذ w .BQQFE5ZQFT $POEJUJPOBM5ZQFTΛۦ࢖ͯ͠ઈରʹܕ෇͚͍ͯ͜͠͏