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));