Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScript Bootcamp 2020

TypeScript Bootcamp 2020

2020年度リクルート新人ブートキャンプ エンジニアコースの講義資料です

Recruit Technologies

August 21, 2020
Tweet

More Decks by Recruit Technologies

Other Decks in Technology

Transcript

  1. About me - ໊শɿ૔ݟ༸ี ʢ@Quramy / ͘ΒΈʔ ͱݺ͹ΕΕΔ͜ͱ͕ଟ͍ʣ - ॴଐɿPE෦

    ASG, ϑϩϯτΤϯυΤϯδχΞ - ৬ྺɿRTCʹདྷͨͷ͸2020/2݄ɻ ࠃ಺SIer -> Webܥϕϯνϟʔ2ࣾʹ͍·ͨ͠
  2. ๻ͱTypeScript - 2015೥3݄5೔͔ΒTS΍ͬͯ·͢ - ౰࣌͸VSCͳ͔ͬͨͷ΋͋ͬͯɺvim޲͚ͷTypeScript pluginΛॻ͍ͨΓ - ࠷ۙ΋ESLint޲͚ͷΤσΟλ֦ு΍GarphQL༻ͷΤσΟλ֦ுΛ࡞ͬͨΓͯ͠ ͍·͢ɻASTܥͷٕज़ׂ͕ͱಘҙͰ͢ -

    https://github.com/microsoft/TypeScript-Website ͰTSຊՈαΠτͷ຋༁׆ಈ ΋͍ͯ͠·͢ɻίϯτϦϏϡʔτ͍ͨ͠ɺͱ͍͏ਓ͕͍ͨΒ੠͔͚͍ͯͩ͘͞ - ࠓ೥2݄։࠵༧ఆͩͬͨTS Conf JPʹCFP௨ͬͨΜ͚ͩͲɺcovid19ͷ͍ͤͰྲྀ Εͨɻɻɻ
  3. ໨࣍ 1. TypeScript is Կ 2. TypeScriptʹ৮ΕΔ ※ 3. ܕͷૢ࡞

    ※ 4. ϥΠϒϥϦͷܕఆٛ 5. TypeScriptͱϞδϡʔϧ 6. TypeScriptͱϏϧυΤίγεςϜ ※
  4. ͍ͬͺ͍͋ΔͧAltJS - AltJS͍Ζ͍Ζ - Flow Type, CoffeeScript, Dart, Reason, Hexa,

    Elm, JSX (not React) , ScalaJS, ClojureScript, asm.js, GopherJS, GWT, etc… - ϒϥ΢βͰಈ͔ͤΔݴޠ͸جຊతʹJavaScript͚ͩͳͷͰ※1 ɺੈͷதʹ͸ ͍ͬͺ͍Alt JS͕͋Γ·͢ - ※1 ࠷ۙ͸WebAssembly΋͋Δ͚ͲɺͦΕ͸আ֎ͨ͠ͱͯ͠ - Ұ࣌ظ͸Ӎޙͷ஛ͷࢠͷ͝ͱ͘ཚཱ͍ͯ͠·͕ͨ͠ɺ࠷ۙ͸TypeScriptʹ ܉഑্͕͕Γͭͭ͋Δؾ഑ 10
  5. ·ͣ͸৮ͬͯΈΑ͏ - TypeScript Playground ʹ͓खܰ؀ڥ͕͋Γ·͢ - ৮ͬͯΈΑ͏Playgroundɿ - Run /

    LogsͰ࣮ߦΛ֬ೝ͠Α͏ - JSλϒ͔ΒτϥϯεύΠϧ͞ΕͨJavaScriptίʔυΛ֬ೝ͠Α͏ 12
  6. ܕνΣοΫ͸બ΂Δ - TypeScript as ઴࣍తܕ෇ͷΑ͍ͱ͜Ζɿ - طଘͷJavaScript͚ͩͰॻ͔ΕͨιʔείʔυʹঃʑʹܕΛ෇͚͍͚ͯΔ - ৽نϓϩδΣΫτͰ͸ɺ࠷ॳ͔Β੩తܕ෇ݴޠͱಉ͡Α͏ʹ࢖͏͜ͱ΋ Ͱ͖Δ

    - TypeScript as ઴࣍తܕ෇ͷ஫ҙ఺ɿ - ॴḨ͸ޙ෇ͷػߏɻJavaScriptͷࣗ༝౓ͱ૬൓͢ΔՕॴ΋͋Δ͠ɺӕͭ ͍ͯܕγεςϜ͕ὃ͞ΕΔ͜ͱ͢Β͋Γಘ·͢ 16
  7. ஫ऍͰ͖Δͱ͜Ζ - ଞʹ΋ : ܕ໊ Ͱ஫ऍͰ͖Δͱ͜Ζ͸৭ʑ͋Γ·͢ const a: string =

    "hoge"; let b: string; var c: string; function d(): string { return "hoge"; } class MyClass { e: string = ""; } 30
  8. Primitive types - ਺஋Ҏ֎ʹ΋ɺจࣈྻ΍ਅِ஋ͳͲ΋primitive typeͱͯ͠༻ҙ͞Ε͍ͯ ·͢ const bool: boolean =

    true; const num: number = 100; const str: string = "hogehoge"; const nullObj: null = null; const undefVal: undefined = undefined; 32
  9. Object / Array type const obj: { name: string, age:

    number } = { name: "Bob", age: 20, }; const arr: number[] = [1, 2, 3]; 34
  10. ϛχԋश - ҎԼΛຬͨ͢ GetUser ͱ͍͏ؔ਺ܕΛॻ͍ͯΈͯ - input: จࣈྻܕ - output:

    ࣍ͷߏ଄Ͱఆٛ͞ΕΔΑ͏ͳUserܕ id จࣈྻ name จࣈྻ age ਺஋ isMarried ਅِ஋ 36
  11. Class type TodoItem = { name: string; }; interface Service

    { getTodos(): TodoItem[]; } class ConcreteService implements Service { private _todos: TodoItem[]; constructor(initialTodos: TodoItem[]) { this._todos = initialTodos; } getTodos() { return this._todos; } } 38
  12. JavaScriptͷClassʹແ͍ػೳ - ϑΟʔϧυɾϝιουʹՄࢹੑ͕ઃఆͰ͖Δ - private / protected / public -

    ※ TypeScriptʹ͓͚Δprivateߏจ͸Soft PrivateɻͦͷؾʹͳΕ͹ΞΫ ηεͰ͖Δ - ந৅Ϋϥε / ந৅ϝιουΛఆٛͰ͖Δ - InterfaceΛ࣮૷Ͱ͖Δ 39
  13. ୅ೖՄೳͱ͸Կ͔ - assignableͷྫ: - showMessageؔ਺͸ɺจࣈྻܕͰ͋Δmessageͱ͍͏ϑΟʔϧυΛ ࣋ͬͨܕͰ͋Ε͹ɺԿͰ΋୅ೖՄೳ type SomeType = {

    message: string; }; function showMessage(obj: SomeType) { console.log(obj.message); } showMessage({ message: “Hello!" }); 44
  14. Interface v.s. Type alias - ϑΟʔϧυ΍ϝιουΛ࣋ͭΦϒδΣΫτͷܕΛఆٛͰ͖Δͱ͍͏ҙຯ Ͱɺtype aliasͱinterfaceʹ͸ػೳͷॏෳ͕͋Γ·͢ interface IHoge

    { message: string; onChangeMessage(cb: (msg: string) => void): void; } type HogeType = { message: string; onChangeMessage(cb: (msg: string) => void): void; }; let hoge1: IHoge; let hoge2: HogeType; /* IHogeͱHogeType͸૒ํʹassignable */ hoge1 = hoge2; hoge2 = hoge1; 47
  15. Interface v.s. Type alias - લϖʔδͷ IHoge interface ͱ HogeType

    ʹ͍ͭͯɺPlayground্Ͱ ͷҧ͍Λ୳ͯ͠Έͯ - લϖʔδͷྫʹɺԼهΛ௥هͨ͠ͱ͖ʹͲ͏ͳΔ͔֬ೝͯ͠Έͯ interface IHoge { errorCode: number; } 48
  16. ԋशͷ΍Γํ - repositoryΛclone - https://github.com/recruit-tech/bootcamp-2020-ts.git - cd server - npm

    i typescript -D - npm i @types/express @types/body-parser -D - npx run tsc —init - .jsϑΝΠϧΛ.tsϑΝΠϧʹϦωʔϜ͢Δ 53 +4ฤͰ࡞Γ͖Ε͍ͯΔͷͰ͋Ε͹ɺ ͦͷίʔυΛ࢖ͬͯ ͜ͷίϚϯυʹ͍ͭͯ͸ޙͰղઆ͠ ·͢
  17. Type error - JavaScriptͷϓϩάϥϜͰ΋ͬͱ΋සൟʹੜ͡Δόά͸ɺnull ·ͨ͸ະఆ ٛͷม਺ʹରͯ͠ɺ஋͕ଘࡏ͢ΔલఏͰΞΫηεͯ͠͠·͏έʔεͰ͢ - ʢ༨ஊʣALGOL WੜΈͷ਌Ͱ͋ΔTony Hoareᐌ͘ʮNullࢀর͸࠷େͷ

    ޡΓͩͬͨɻίϯύΠϧͰ͢΂ͯνΣοΫͰ͖ΔΑ͏ʹ͔ͨͬͨ͠ʯ - https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony- Hoare/ 59 Uncaught TypeError: Cannot read property ‘hoge' of undefined
  18. Optional - ΦϓγϣϯͷstrictNullCheck͕trueͷ৔߹ɺoptionalͳ஋Λ͍͖ͳΓૢ ࡞͠Α͏ͱ͢ΔͱTypeScript͕ίϯύΠϧΤϥʔʹͯ͘͠Ε·͢ ʢίϯύΠϧΤϥʔ͸͝๙ඒͩͱࢥ͍·͠ΐ͏ʣ function fn(args: { message?: string})

    { // ࣄલʹargs.messageͷଘࡏΛνΣοΫ͢Δඞཁ͕͋Δ if (!args.message) return ""; return args.message.toLowerCase(); } fn({}); // messageΛলུՄೳ 61
  19. ͦͷଞͷOptionalදݱ - ϓϩύςΟ໊ޙͷ ? Ҏ֎ʹ΋Optionalม਺Λදݱ͢Δํ๏͕͋Γ·͢ - ※ ύΠϓه߸ͷҙຯ͸ޙड़͠·͢ // ؔ਺ͷoptionalҾ਺

    function hoge(a: number, b?: number) { } // null ΍ undefined ͱͷUnion type X = string | undefined; type Y = string | null;
  20. strictNullCheck ʹ͍ͭͯ - strictNullChecks͸ɺࢀর͍ͯ͠Δ஋ͷܕʹnull ·ͨ͸ undefined͕୅ೖ Մೳͳ৔߹ʹɺͦͷ஋ͷૢ࡞Λ੍ݶ͢ΔػೳͰ͢ - TypeScriptͷσϑΥϧτઃఆͰ͸ɺstrictNullCheck͸ONͰ͢ -

    جຊతʹ͸༗ޮʹ͓͍ͯͨ͠ํ͕ྑ͍ػೳͰ͕͢ɺطଘͷJavaScriptϓ ϩδΣΫτʹޙ෇ͰTypeScriptΛಋೖ͢Δ৔߹͸ɺҰ୴offʹ͢Δͷ΋Ξ ϦͰ͢ 63
  21. Literal type - ਺஋/จࣈྻ/ਅِ஋ܕ͸ɺͦΕͧΕͷ஋ͦͷ΋ͷΛܕͱͯ͠࢖͏͜ͱ͕ Ͱ͖·͢ɻ͜ΕΛLiteral Typeͱݺͼ·͢ type SomeString = "some

    string"; type SomeNumber = 1; type True = true; function fn(str: SomeString) { return str.trim(); } fn("some string"); // OK fn("other string"): // Error 65
  22. Union type - ෳ਺ͷܕΛύΠϓه߸ʢ | ʣͰ۠੾Δ͜ͱͰɺUnion Typeʢ࿨ܕ, ڞ༻ମ ܕͱ΋ʣΛએݴ͠·͢ -

    String literal typeͱซ༻͢Δͱɺྻڍܕͱಉ͡Α͏ʹѻ͏͜ͱ΋Ͱ͖· ͢ʢTypeScriptʹ΋enumߏจ͕༻ҙ͞Ε͍ͯ·͕͢ɺ͋·Γར༻͞Ε·ͤΜʣ type NumOrStr = string | number; type MaybeStr = string | null | undefined; type Colors = "red" | "blue" | "green" | "yellow"; 66
  23. ܕͷߜΓࠐΈ - Union Type͸ɺifจ΍switchจͰ஋ΛνΣοΫ͍ͯ͘͜͠ͱͰɺΑΓৄࡉ ͳܕ΁ߜΓࠐΉ͜ͱ͕Ͱ͖·͢ɻ͜ΕΛType GuardͱΑͼ·͢ - strictNullCheckͰઆ໌ͨ͠ifจʹΑΔߜΓࠐΈ΋Type GuardͷҰछͰ͢ function

    fn(input: string | number) { console.log(input.toString()); if (typeof input === "number") { console.log(200 * input); } else { console.log(input.trim()); } } 67
  24. Type Guardͷछྨ - ͍͔ͭ͘ͷߏจ͕Type Guardͱͯ͠ར༻Ͱ͖·͢ɿ - typeof x === “string”,

    x instanceof HogeClass - Literal typeʹ͓͚Δಉ஋֬ೝʢ if (x === “some message”) ʣ - obj.x ΍ obj[“x”] ΍ x in objͳͲͷଘࡏ֬ೝ - User Defined Type Guard function: function fn(x: any): x is { msg: string } { return x.msg && typeof x.msg === "string"; } 68
  25. ϛχԋश̍ - ҎԼͷؔ਺͸ type ʹԠͯ͡ɺpayload ͷܕ͕ҟͳΓ·͢ɻ ίϯύΠϧ͕௨ΔΑ͏ʹɺAction ͷܕΛߟ͑ͯΈͯ 69 function

    reduce(state = [100], action: Action) { switch (action.type) { case “CONCAT": // payload: number[] return state.concat(action.payload); case “REMOVE": // payload: number return state.filter(val => val !== action.payload); default: return state; } };
  26. ϛχԋश̎ - ࣍ͷίʔυ͸੺Լઢ෦෼ͰίϯύΠϧΤϥʔͱ͞Εͯ͠·͍·͢ɻԿ ނͰ͠ΐ͏͔ʁ const prices = [1000, 500]; type

    Item = { price?: number; }; function fn(item: Item): boolean { if (item.price == null) return false; return prices.some( p => item.price > p, ); } 70
  27. Ωϟετ - จࣈྻͷLiteral type͸stringܕʹ୅ೖՄೳͰ͕͢ɺ stringܕ͸จࣈྻͷLiteral typeʹ͸୅ೖͰ͖·ͤΜ - ʮ୅ೖՄೳʯ͸ɺSub typeʢ۩৅ʣˠ Supar

    typeʢந৅ͳܕʣͷํ޲ʹ ݶఆ͞ΕΔ͔ΒͰ͢ type SomeString = "some string"; const x: SomeString = "some string"; const y: string = x; const z: SomeString = y; Supar type Sub type type SomeString string
  28. Ωϟετ - ͜ͷΑ͏ͳ৔߹ɺม਺ͷޙΖʹ as ܕ໊ Λ෇༩͢Δ͜ͱͰܕΛม׵Ͱ͖ ·͢ʢਖ਼ࣜʹ͸ ΩϟετͰ͸ͳ͘ɺType assetion ͱݺ͹ΕΔػೳʣ

    Supar type Sub type type SomeString string type SomeString = "some string"; const x: SomeString = "some string"; const y: string = x; const z = y as SomeString;
  29. asͷ੍໿ - asͰม׵Ͱ͖Δͷ͸ɺSupar type → Sub type ͷ৚͕݅ຬͨ͞ΕΔͱ͖ ͷΈͰ͢ -

    e.g. numberܕ͸stringܕʹม׵Ͱ͖·ͤΜ Supar type Sub type type SomeString string
  30. Generics type List<T> = T[]; function getLength<T>(list: List<T>) { list.length;

    } interface IFoo<T> { list: ReadonlyArray<T>; } class Foo<T> implements IFoo<T> { constructor(public readonly list: T[]){ } get size() { return getLength(this.list); } } const foo = new Foo<string>([""]); 80
  31. Generics // ໭Γ஋͕Promise<{ id: number; name: string; }> function getTodo()

    { return Promise.resolve({ id: 100, name: "hoge", }); } const index = new Map<number, string>(); index.set(1, "hoge"); index.has(1); const colors: ReadonlyArray<string> = [ "red", "green", "blue", ]; colors.sort(); // ഁյૢ࡞͸ېࢭ
  32. ԋशͷ΍Γํ - repositoryΛcloneʢԋश1ͱಉ͡ͱ͜Ͱ͢ - https://github.com/recruit-tech/bootcamp-2020-ts.git - cd client - npm

    init -y - npm i typescript -D - npx run tsc —init - js/**/*.jsΛ.tsʹॻ͖׵͑Δ - npx run tsc --watch 85
  33. ʢิ଍ʣimport / export - TypeScriptʹ͓͚ΔʮϞδϡʔϧʯʹ͍ͭͯ͸ผ్ޙड़͠·͢ - ͜ͷԋशͰ͸ɺES2015ͷ import / export

    ߏจ͕ͦͷ··ར༻Ͱ͖· ͢ɻಛʹ import จ΍ export จΛॻ͖׵͑Δඞཁ͸͋Γ·ͤΜ 87
  34. Advanced type - ࠓ೔͸ׂѪ͠·͕͢ɺܕγεςϜʹ͸ΑΓߴ౓ͳػೳ΋༻ҙ͞Ε͍ͯ· ͢ - Mapped type: objectܕͷkeyΛ࠶ར༻ͯ͠ผͷܕΛ࡞Δ -

    Conditional type: ୅ೖՄೳੑͰܕΛύλʔϯϚον - Type inference in conditional type: ύλʔϯϚονͨ͠ܕͷ࠶ར༻ 91
  35. Advanced type interface Observable<T> { subscribe(cb: (v: T) => void):

    void; } type Unboxing<T> = T extends Observable<infer S> ? S : never; declare function combineLatest<U extends Observable<any>[]>( ...args: U ): Observable< { [P in keyof U]: Unboxing<U[P]>; } >; declare const s1: Observable<string>; declare const s2: Observable<number>; declare const s3: Observable<boolean>; combineLatest(s1, s2, s3).subscribe(([v1, v2, v3]) => { });
  36. 1. NPM ύοέʔδʹܕఆ͕ٛಉ ࠝ͞Ε͍ͯΔ - npm install (ϥΠϒϥϦ໊) Λ࣮ߦ͢Δ͚ͩͰܕఆ͕ٛར༻ՄೳʹͳΓ· ͢

    - ͜ͷखͷ΍ͭ͸ɺϥΠϒϥϦͷpackage.jsonʹ “types”: “index.d.ts” ͱ ͍ͬͨهड़͕͋Γ·͢ 100
  37. ௥Ճ՝୊ - ԋश1͕ૣ͘௥ΘͪΌͬͨਓ޲͚ - expressʹ͸ϛυϧ΢ΣΞͱ͍͏࢓૊ΈͰɺϢʔβʔଆͰ Request / ResponseͷΦϒδΣΫτΛ֦ுͰ͖·͢ const app

    = express(); app.use((req, res, next) => { req.isAuthenticated = true; next(); }); app.get("/api/v1/todos", (req, res) => { console.log(req.isAuthenticated); // ͦͷଞͷॲཧ }); ͜ͷ෦෼͕ϛυϧ΢ΣΞ ϛυϧ΢ΣΞͰ௥Ճ͞ΕͨϑΟʔϧυ 105
  38. ES2015 Ϟδϡʔϧ // calc.js // ϞδϡʔϧΛར༻͢Δଆ import { add }

    from “./add.js”; console.log(add(1, 2)); // add.js // ϞδϡʔϧΛఆٛ͢Δଆ export function add(a, b) { return a + b; }
  39. CommonJSͷϞδϡʔϧ // calc.js // ϞδϡʔϧΛར༻͢Δଆ const add = require("./add"); console.log(add(1,

    2)); // add.js // ϞδϡʔϧΛఆٛ͢Δଆ function add(a, b) { return a + b; } module.exports = add;
  40. ʢ༨ஊʣଞͷ--moduleୡ - --module ʹ͸ “amd” / “umd” / “system” ͷ஋΋બ୒ՄೳͰ͢ɻ…͕໓ଟ

    ʹ࢖͏͜ͱ͸ͳ͍Ͱ͢ - ڵຯ͕͋ͬͨΒɺ“RequireJS” ͱ͔ “SystemJS” Ͱௐ΂ͯΈΔͱྑ͍ͱࢥ ͍·͢ 115
  41. TypeScriptͱͯ͠ͷϞδϡʔϧ - Ϟδϡʔϧͱͯ͠ղऍ͞ΕΔ.tsϑΝΠϧ - ϞδϡʔϧʹͳΒͳ͍.tsϑΝΠϧ /* types.ts */ // Todo

    ΠϯλʔϑΣΠε͸Ͳ͔͜ΒͰ΋ࢀরՄೳ interface Todo { name: string; } /* types.ts */ // Todo ΠϯλʔϑΣΠε import ͠ͳ͍ͱࢀরͰ͖ͳ͍ export interface Todo { name: string; } 117
  42. Ϗϧυπʔϧͷཚཱ - Ϟδϡʔϧϩʔμʔ - CommonJS (Node.js) ελΠϧ, RequireJSελΠϧ, etc… -

    ϏϧυγεςϜ - Grant, Gulp, etc… - ѹॖʢ೉ಡԽʣπʔϧ - YUI Compressor, ClosureCompiler, UglifyJS, etc… 121
  43. Ϗϧυπʔϧͷཚཱ - Ϟδϡʔϧϩʔμʔ - CommonJS (Node.js) ελΠϧ, RequireJSελΠϧ, etc… -

    ϏϧυγεςϜ - Grant, Gulp, etc… - ѹॖʢ೉ಡԽʣπʔϧ - YUI Compressor, ClosureCompiler, UglifyJS, etc… 122 ͱʹ͔͘৭ʑ͋ͬͨʂ
  44. ESLint - ESLint ͸ASTʢந৅ߏจ໦ʣΛ༻͍ͨίʔυͷνΣοΫπʔϧͰ͢ɻې ࢭ͍ͨ͠ίʔυύλʔϯΛϧʔϧͱͯ͠ొ࿥ͯ͠ར༻͠·͢ - ϧʔϧͷྫ: - consoleΛ࢖Θͳ͍͜ͱ -

    ࠶୅ೖ͠ͳ͍ม਺ʹ͸letͰ͸ͳ͘constΛ༻͍Δ͜ͱ - TypeScriptͱESLintΛซ༻͢Δ৔߹ɺhttps://github.com/typescript- eslint/typescript-eslint Λ࢖͍·͢
  45. ͓ΘΓʹ - ࠓ೔͸ԼهͳͲΛத৺ʹֶΜͰ͖·ͨ͠ - TypeScriptͷجຊจ๏ - طଘͷJavaScriptίʔυʹܕΛಋೖ͢Δํ๏ - TypeScriptͷϓϩδΣΫτʹ͓͚ΔϏϧυͷํ๏ -

    ࣌ؒͷ౎߹্ɺ৮Ε͍ͯͳ͍τϐοΫ΋·ͩ୔ࢁ͋Γ·͢ɻؾʹͳΔ ςʔϚ͕͋ͬͨΒɺੋඇࣗ෼Ͱௐ΂ɺʢՄೳͰ͋Ε͹ʣखΛಈ͔ͯ͠Έ ͍ͯͩ͘͞