TypeScript 类型学习4
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));