TypeScript 型別學習4
阿新 • • 發佈:2022-04-06
interface Shape { kind: "circle" | "square"; //為了避免錯誤,規定的字面量型別 radius?: number; sideLength?: number; } function handleShape(shape: Shape) { if (shape.kind === "circle" && shape.radius) return Math.PI * shape.radius ** 2; //但是!不推薦使用 } interface Circle { kind: "circle"; radius: number; } interface Square { kind: "square"; sideLength: number; } interface Sun { kind: "sun"; sideLength: number; } /** * 可辨識聯合 */ type AreaShape = Circle | Square | Sun; function getArea(shape: AreaShape) { switch (shape.kind) { case "square": return shape.sideLength ** 2; case "circle": return Math.PI * shape.radius ** 2; } } /** * never型別和完整性檢查 永不存在的值的型別 * 在 switch 當中判斷 type,TS 是可以收窄型別的; * 但是如果加入新的同事,新的同事給你加了新的型別,但是他忘了給你對應的邏輯。 * 當沒有涵蓋所有可辨識聯合的變化時,我們想讓編譯器可以通知我們。 * never就起了作用併產生一個編譯錯誤。所以通過這個辦法,你可以確保 getKind 總是窮盡了所有 AreaShape 的可能型別。 */ function getKind(shape: AreaShape) { switch (shape.kind) { case "square": return shape.sideLength ** 2; case "circle": return Math.PI * shape.radius ** 2; case "sun": return Math.PI * shape.sideLength ** 2; default: const _check: never = shape; return _check; } } /** * 函式型別表示式 * fn:(a:string)=>void */ type GreeterFunction = (a: string) => void; function greeter(fn: GreeterFunction) { fn("函式型別表示式"); } function printToConsole(s: string) { console.log(s); } greeter(printToConsole); /** * 呼叫簽名 */ // type DescribeFunction = { // describction: string; // (someArg: number): boolean; // }; // function handleSomthing(fn: DescribeFunction) { // console.log(fn.describction + "return" + fn(999)); // } // function call(n: number) { // console.log(n); // return true; // } // call.describction = "hello"; // handleSomthing(call); /** * 泛型函式 可以使用泛型來建立可重用的元件 * @param arg * @returns 使用any型別會導致這個函式可以接收任何型別的arg引數, * 這樣就丟失了一些資訊:傳入的型別與返回的型別應該是相同的。 * T是型別變數 * 使用後可以讓我們去跟蹤使用的型別的資訊 * 怎麼使用型別變數 */ function TypeAcceptAny(arg: any) { return arg; } let ssss = TypeAcceptAny("232"); function TypeAccept<B>(arg: B) { return arg; } function TypeArray<Type>(arr: Type[]) { return arr[0]; } /** * 第一種型別明確寫法 * 第二種型別推論寫法 更普遍 * 但是如果編輯器不能自動推斷出型別的話,就應該明確的傳入型別 * 需要注意的點 * 建立泛型函式時,編譯器要求你在函式體必須正確的使用這個通用的型別。 */ let color = TypeAccept<string>("#fff"); let age = TypeAccept(18); let number = TypeArray([1, 2]); let string = TypeArray(["1"]); /** * 泛型不光可以定義一個 也可以定義多個 */ function MapItem<Input, Output>( arr: Input[], fun: (arg: Input) => Output ): Output[] { return arr.map(fun); } const parse = MapItem(["1", "2", "3"], (n) => parseInt(n));