5.字面量类型守护(Discriminated Unions)
function printValue(value: string | number) { if (typeof value === "string") { console.log("The value is a string:", value.toUpperCase()); } else { console.log("The value is a number:", value.toFixed(2)); } } // 堆代码 duidaima.com printValue("Hello"); // The value is a string: HELLO printValue(123.456); // The value is a number: 123.46在这个例子中,typeof 通过检查 value 是 string 还是 number 来选择合适的操作。
class Dog { bark() { console.log("Woof!"); } } class Cat { meow() { console.log("Meow!"); } } function makeSound(animal: Dog | Cat) { if (animal instanceof Dog) { animal.bark(); // Safe to call bark() here } else { animal.meow(); // Safe to call meow() here } } const myDog = new Dog(); const myCat = new Cat(); makeSound(myDog); // Woof! makeSound(myCat); // Meow!在这个例子中,instanceof 检查对象是否是 Dog 或 Cat 的实例,以选择调用哪个方法。
interface Car { drive(): void; } interface Boat { sail(): void; } function move(vehicle: Car | Boat) { if ("drive" in vehicle) { vehicle.drive(); // Safe to call drive() here } else { vehicle.sail(); // Safe to call sail() here } } const car: Car = { drive() { console.log("Driving the car"); }, }; const boat: Boat = { sail() { console.log("Sailing the boat"); }, }; move(car); // Driving the car move(boat); // Sailing the boat这里,in 操作符检查 vehicle 是否有 drive 属性,以此决定执行 drive() 或 sail()。
interface Fish { swim(): void; } interface Bird { fly(): void; } function isFish(animal: Fish | Bird): animal is Fish { return (animal as Fish).swim !== undefined; } function moveAnimal(animal: Fish | Bird) { if (isFish(animal)) { animal.swim(); // TypeScript knows `animal` is a Fish } else { animal.fly(); // TypeScript knows `animal` is a Bird } } const fish: Fish = { swim() { console.log("The fish is swimming"); }, }; const bird: Bird = { fly() { console.log("The bird is flying"); }, }; moveAnimal(fish); // The fish is swimming moveAnimal(bird); // The bird is flying在这个例子中,isFish 是一个自定义类型保护函数。它检查 animal 是否为 Fish,并根据类型来调用相应的方法。
interface Square { kind: "square"; size: number; } interface Rectangle { kind: "rectangle"; width: number; height: number; } interface Circle { kind: "circle"; radius: number; } type Shape = Square | Rectangle | Circle; function getArea(shape: Shape): number { switch (shape.kind) { case "square": return shape.size * shape.size; case "rectangle": return shape.width * shape.height; case "circle": return Math.PI * shape.radius * shape.radius; default: return 0; } } const square: Square = { kind: "square", size: 5 }; console.log(getArea(square)); // 25在这个例子中,Shape 类型是由 Square, Rectangle 和 Circle 组成的联合类型,它们都有 kind 字段,通过这个字段我们可以区分出当前的具体类型并相应处理。
字面量类型守护(Discriminated Unions): 使用区分字段来区分联合类型中的不同类型。