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

TypeScript Bootcamp 2020

TypeScript Bootcamp 2020

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

Avatar for Recruit Technologies

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ͷϓϩδΣΫτʹ͓͚ΔϏϧυͷํ๏ -

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