Share
Embed
Transcript
78 slides
-
ܕνΣοΫͱਪ w ؔTVNͷΓOVNCFSͰ͋Δ͜ͱΛਪ͢Δ function sum(a: number, b: number) { return
a + b; } console.log(sum(1, sum(1, 1))); // OK // Argument of type '"a"' is not assignable to // parameter of type 'number' console.log(sum('a', 'b')); -
4USVDUVBM4VCUZQJOH class Hoge { name = "Kurami"; } class Foo
{ name = "Quramy"; } function sayHello(obj: { name: string }) { console.log(obj.name); } sayHello(new Hoge()); sayHello(new Foo()); sayHello(new Error("error")); -
༨ஊ /PNJOBMʹ͍ͨ͠ͱ͖ w ͨ·ʹߏత෦ܕͩͱࠔΔ͜ͱ͕͋Δ w QSJWBUFϑΟʔϧυΛ͏ϋοΫͰճආ͢Δ class DateISOString { private
_ = Symbol("DateISOString"); readonly isoString = new Date().toISOString(); } function hoge(x: DateISOString) { console.log(x.isoString); } hoge(new DateISOString()); hoge({ isoString: "hoge" }); // Error -
4USJDUDIFDL w TUSJDUΦϓγϣϯʢσϑΥϧτͰPOʣΛ͚͓ͯ͘ͱɺݎ ࿚ͳνΣοΫ͕Մೳʹ function hoge(x?: string) { //Object is
possibly 'undefined'. return x.trim(); } function hoge(x?: string) { if (!x) return ""; return x.trim(); // OK } -
ϥΠϒϥϦͷܕఆٛ w ༗໊ͳϥΠϒϥϦOQNJ!UZQFϥΠϒϥϦ໊Ͱܕఆٛ ͕ެ։͞Ε͍ͯΔ npm i @types/node import path from
"path"; export function hoge() { const x = path.join("src", "main.ts"); } -
FT.PEVMFT*OUFSPQ w /PEFKTͰɺ$PNNPO+4͔ΒOBNFEJNQPSU͢ΔͱΤ ϥʔʹ /* hoge.mjs */ import { readFile
} from "fs"; $ node --experimental-modules hoge.mjs SyntaxError: The requested module does not provide an export named ‘readFile' at checkComplete (internal/loader/ModuleJob.js:75:27) at moduleJob.linked.then (internal/loader/ModuleJob.js: 58:11) at <anonymous> -
FT.PEVMFT*OUFSPQ w Ұํɺ5ZQF4DSJQUͰඇ&4.PEVMFT͔ΒͷEFGBVMU JNQPSUར༻Ͱ͖ͳ͔ͬͨͨΊɺ$PNNPO+4ΛJNQPSU͢ ΔʹɺOBNFEJNQPSUͰهड़͢Δ͔͠ͳ͔ͬͨ import * as fs from
"fs"; import { readFile } from "fs"; -
FT.PEVMFT*OUFSPQ w WYҎ߱Ͱɺ$PNNPO+4͔ΒͷEFGBVMUJNQPSU͕ڐ༰͞ ΕΔΑ͏ʹͳͬͨ w ैདྷͷOBNFEJNQPSUͷॻ͖ํґવڐ༰͞Ε͍ͯΔͷ ͷɺ5ZQF4DSJQUެࣜʹEFGBVMUJNQPSUͷॻ͖ํΛਪͯ͠ ͍Δɻ IUUQTXXXUZQFTDSJQUMBOHPSHEPDTIBOECPPLSFMFBTF OPUFTUZQFTDSJQUIUNMTVQQPSUGPSJNQPSUEGSPN
DKTGPSNDPNNPOKTNPEVMFTXJUIFTNPEVMFJOUFSPQ import fs from "fs"; -
.BQQFE5ZQF.PEJpFS w WYͰಋೖ w ैདྷͷ.BQQFE5ZQFͰɺSFBEPOMZ Λ༩͢Δ͜ͱ Ͱ͖ͯɺղআ͢Δ͜ͱͰ͖ͳ͔ͬͨ type Optional<T> =
{ [P in keyof T]?: T[P] }; type ReadOnly<T> = { readonly [P in keyof T]: T[P] }; -
XJUINPEJpFS w ͷ༩Ͱɺ࡞༻ͷ͖ ͚Δ֎͢ ΛදݱՄೳʹ type Optional<T> = { [P
in keyof T]+?: T[P] }; type Strict<T> = { [P in keyof T]-?: T[P] }; type ReadOnly<T> = { +readonly [P in keyof T]: T[P] }; type Mutable<T> = { -readonly [P in keyof T]: T[P] }; -
XJUINPEJpFS type Strict<T> = { [P in keyof T]-?: T[P]
}; // Property 'name' is missing in type '{}' // but required in type 'Strict<{ name?: string | undefined; }>'. const x: Strict<{ name?: string }> = { }; -
$POEJUJPOBMUZQFT w WYͰಋೖ w "TTJHOBCMFΛ݅ͱͯ͠ذ͢ΔܕΛදݱՄೳ w ʮܕ5͕ܕ6ͷ෦ܕͰ͋Εɺܕ9ɺͦ͏Ͱͳ͚Εܕ:ʯ ͱ͍͏ҙຯ type MyType<T,
U, X, Y> = T extends U ? X : Y; -
-FUTUZQF w ༡ΜͰΈΑ͏$POEJUJPOBM5ZQFT w %J⒎ w %J⒎ͲΜͳܕͰ͠ΐ͏͔ʁ type DiffKey<K1, K2>
= K1 extends K2 ? never : K1; type $Diff<T, U> = { [P in DiffKey<keyof T, keyof U>]: T[P]; }; -
%JTUSJCVUJPO w $POEJUJPOBM5ZQFTͱ6OJPO5ZQFTͷؒʹཱ͕ w OFWFS͍͔ͳΔܕʹೖෆՄೳͳܕʢϘτϜܕʣ w type DiffKey<K1, K2> =
K1 extends K2 ? never : K1; let key: DiffKey<("name" | "age"), "age">; // ("name" extends "age" ? never : "name") // | ("age" extends "age" ? never : "age") // = ("name" | never) // = "name" -
$POEJUJPOJONBQQFEUZQFT w %J⒎,FZLFZPG5 LFZPG6ʮܕ5ͷLFZશମ͔Βɺܕ6 ͷLFZશମͷू߹ΛҾ͍ͨू߹ʯ w .BQQFE5ZQF͋ΔLFZͷू߹ʹର͢ΔϓϩύςΟͷϚο ϐϯά type $Diff<T,
U> = { [P in DiffKey<keyof T, keyof U>]: T[P]; }; -
%J⒎ͷਖ਼ମ w 'MPXUZQFʹಉ໊ͷ6UJMJUZUZQF͕͋Γ·͢ type DiffKey<K1, K2> = K1 extends K2
? never : K1; type $Diff<T, U> = { [P in DiffKey<keyof T, keyof U>]: T[P]; }; const defaultProps = { age: 0 }; let requiredProps: $Diff<{ name: string; age: number; }, typeof defaultProps>; requiredProps = { name: "Quramy" }; -
*OGFSBOE$BQUVSF w ਖ਼نදݱͷΩϟϓνϟϦϯάʢάϧʔϓԽʣͱࣅ͍ͯΔ w Ϛονͨ͠άϧʔϓ෦Λޙ͔Βར༻Ͱ͖Δ const regexp = /hoge(\d+)/; const
hit = "hoge10".match(regexp); console.log(hit[1]) // 10 -
*OGFSBOE$BQUVSF w 5͕ؔͰ͋ΕɺͦͷΓͱͯ͠ਪ͞ΕΔܕ͕3ʹ֨ ೲ͞ΕΔ type Return<T> = T extends (...args:
any[]) => infer R ? R : never; let r: Return<() => number>; // typeof r = number -
3FEVYͬΆ͍ΞϨ type Return<T> = T extends (...args: any[]) => infer
R ? R : never; type AppState<T> = { [P in keyof T]: Return<T[P]> }; const reducers = { name: (state: string, action: any) => state, age: (state: number, action: any) => state, }; let appState: AppState<typeof reducers>; // typeof appState = { name: sting, age: number } -
VOLOPXOUZQF w WYͰಋೖ w VOLOPXOͯ͢ͷܕ͕BTTJHOBCMF w VOLOPXOUZQFɺUZQFBTTFSUJPO͠ͳ͍ͱԿͰ͖ͳ͍ function hoge(x: unknown)
{ if (typeof x === "string") { console.log(x.toLowerCase()); } } hoge(10); hoge("foo"); -
5VQMFTJOSFTUQBSBNFUFST BOETQSFBEFYQSFTTJPOT w WYͰɺؔҾʹؔ͢Δܕͷهड़ྗ͕ڧԽ͞Εͨ w 3FTUQBSBNFUFSTXJUIUVQMFUZQFT w 4QSFBEFYQSFTTJPOTXJUIUVQMFUZQFT w (FOFSJDSFTUQBSBNFUFST
w 0QUJPOBMFMFNFOUTJOUVQMFUZQFT w 3FTUFMFNFOUTJOUVQMFUZQFT -
3FTUQBSBNFUFSTXJUI UVQMFUZQFT w WYҎલ3FTU1BSBNFUFS"SSBZUZQFͷΈ͕ڐ༰ w WY͔Β5VQMFUZQFར༻Մೳʹ function hoge(...args: any[]) {
const a1 = args[0]; const a2 = args[1]; const a3 = args[2]; } function foo(...args: [string, number]) { const a0 = args[0]; // string const a1 = args[1]; // number const a2 = args[2]; // error } -
4QSFBEFYQSFTTJPOTXJUI UVQMFUZQFT w 4QSFBE0QFSBUPSʹΑΔؔݺͼग़͠ʹରԠ ҎલDPNQJMFFSSPSʹͳͬͯ͠·͍ͬͯͨ w WY͔Β5VQMFUZQFར༻Մೳʹ declare function
foo(a: number, b: number): void; const args1 = [1, 2] as [number, number]; foo(...args1); const args2 = [1, "bar" ] as [number, string]; // Argument of type 'string' is not assignable to // parameter of type 'number'. foo(...args2); -
(FOFSJDSFTUQBSBNFUFST w 3FTU1BSBNFUFSTʹ૯শܕ͕ར༻Մೳʹ w +BWB4DSJQUGVODUJPOͷCJOEDBMMBQQMZͱͷੑ্ ޙड़ͷTUSJDU#JOE$BMM"QQMZͷૅ declare function curry<T, U
extends any[], R>( fn: (x: T, ...args: U) => R ): (x: T) => (...args: U) => R; const sum = (a: number, b: number) => a + b; const bound = curry(sum)(1); const x = bound(2); // type of x = number const error = bound("hoge"); // error -
0QUJPOBMFMFNFOUTJOUVQMF UZQFT w 5VQMF5ZQFͷதͰ NPEJpFS͕ར༻Մೳʹ w 3FTU1BSBNFUFSTΛ5VQMF5ZQFͰड͚ΕΔΑ͏ͳͬͨ͜ ͱʹΑΔ෭࢈ type Tuple
= [number, string?]; const x1: Tuple = [1]; const x2: Tuple = [1, "foo"]; -
3FTUFMFNFOUTJOUVQMF UZQFT w 5VQMF5ZQFதʹ3FTUͳUZQFΛදݱͰ͖ΔΑ͏ʹͳͬͨ w ؔͷ3FTU1BSBNFUFSTͱͯ͠ར༻Մೳ function hoge<T extends any[]>(...args:
T) { return args; } const arr = [1, 2, 3]; const v = hoge("hoge", ...arr); // typeof v = [string, ...number[]] type Hoge = [string, ...number[]]; -
Y type Box<V> = { value: V }; type Boxing<T>=
{ [P in keyof T]: Box<T[P]>; }; type User = { name: string, age: number, }; const boxedUser: Boxing<User> = { name: { value: "quramy" }, age: { value: 18 }, }; let boxedNumbers: Boxing<number[]>; boxedNumbers.concat.value([]); // ??? boxedNumbers.length.value; // ??? -
Y w LFZPGOVNCFS<>ͷҙຯ͕มΘͬͨΘ͚Ͱͳ͍ʹҙ type Box<V> = { value: V };
type Boxing<T>= { [P in keyof T]: Box<T[P]>; }; const boxedNumbers: Boxing<number[]> = [ { value: 1 }, { value: 100 }, ]; -
͍Έͪ w $POEJUJPOBMUZQF (FOFSJDSFTUQBSBNFUFST .BQQFE UVQMFUZQFͷ߹ΘٕͤͷྫΛհ w ͓SYKTͷDPNCJOF-BUFTUؔʢ˞1SPNJTFBMMతͳౕʣ interface Observable<T>
{ subscribe(cb: (v: T) => void): void; } declare var s1$: Observable<string>; declare var s2$: Observable<number>; combineLatest(s1$, s2$).subscribe(([s1, s2]) => { console.log(s1); // typeof s1 = string console.log(s2); // typeof s2 = number }); -
͍Έͪ interface Observable<T> { subscribe(cb: (v: T) => void): void;
} // Inference in conditional type type StreamType<T> = T extends Observable<infer S> ? S : never; // Mapped tuple type type Unboxing<U extends Observable<any>[]> = { [P in keyof U]: StreamType<U[P]>; }; // Generic rest parameters declare function combineLatest<U extends Observable<any>[]> (...args: U): Observable<Unboxing<U>>; -
TUSJDU#JOE$BMM"QQMZ w CJOE declare function hoge(a: number, b: string): void
const hoge1 = hoge.bind(null, 1); hoge1("hoge"); hoge1(); // error hoge1(1); // error hoge1("hoge", 2); // error -
TUSJDU#JOE$BMM"QQMZ w DBMM declare function hoge(a: number, b: string): void
hoge.call(null, 1, "hoge"); hoge.call(null, 1); // error hoge.call(null, "hoge"); // error hoge.call(null, 1, "hoge", 2); // error -
TUSJDU#JOE$BMM"QQMZ w BQQMZ declare function hoge(a: number, b: string): void
hoge.apply(null, [1, "hoge"]); hoge.apply(null, [1]); // error hoge.apply(null, ["hoge"]); // error hoge.apply(null, [1, "hoge", 2]); // error -
%FNP /* before */ import { hoge } from "./lib";
import { foo } from "./lib"; // no used import import { bar } from "./lib"; hoge(); foo(); /* after */ import { hoge, foo } from "./lib"; hoge(); foo(); -
&SSPS$PEFpY w UTTFSWFS -BOHVBHF4FSWJDF ʹ͓͚ΔΤϥʔpYͷྲྀΕ HFU4VQQPSUFE$PEF'JYFTίϚϯυͰ-BOH4FSWJDF͕ରԠՄೳͳ ΤϥʔίʔυͷҰཡΛऔಘ͓ͯ͘͠ HFU&SSPSίϚϯυͰϑΝΠϧͷΤϥʔΛ-BOH4FSWJDF͍߹Θ
ͤΔ $PEF'JYαϙʔτରͷΤϥʔίʔυͷ߹ɺHFU$PEF'JYFTίϚ ϯυͰमਖ਼༰Λ-BOH4FSWJDFʹ͍߹ΘͤΔ ड͚औͬͨมߋ༰ 5FYU$IBOHF ΛΤσΟλͷόοϑΝʹద༻͢Δ -
3FOBNFJNQPSU EFDMBSBUJPO w WYͰಋೖ w *NQPSUGSPNͷର෦ΛSFOBNFͰ͖ΔΑ͏ʹͳͬͨ /* fuga.ts */ export
function fuga() { return "hoge"; } /* main.ts */ import { fuga } from "./fuga"; console.log(hoge());