在 TypeScript 中,要获取一个联合类型所代表的具体类型,我们通常使用类型守卫(Type Guards)或类型断言(Type Assertions)。以下是几种常用的方法:
- 使用 typeof 类型守卫:
对于基本类型,我们可以使用 typeof 操作符:
type StringOrNumber = string | number;
function processValue(value: StringOrNumber) {
if (typeof value === 'string') {
console.log('It\'s a string:', value.toUpperCase());
} else {
console.log('It\'s a number:', value.toFixed(2));
}
}- 使用 instanceof 类型守卫:
对于类的实例,我们可以使用 instanceof 操作符:
class Dog {
bark() { console.log('Woof!'); }
}
class Cat {
meow() { console.log('Meow!'); }
}
type Animal = Dog | Cat;
function makeSound(animal: Animal) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}- 使用自定义类型守卫:
对于更复杂的类型,我们可以定义自己的类型守卫函数:
interface Square {
kind: 'square';
size: number;
}
interface Rectangle {
kind: 'rectangle';
width: number;
height: number;
}
type Shape = Square | Rectangle;
function isSquare(shape: Shape): shape is Square {
return shape.kind === 'square';
}
function calculateArea(shape: Shape) {
if (isSquare(shape)) {
return shape.size * shape.size;
} else {
return shape.width * shape.height;
}
}- 使用 in 操作符:
对于对象类型,我们可以使用 in 操作符检查属性是否存在:
type Bird = { fly: () => void };
type Fish = { swim: () => void };
function move(animal: Bird | Fish) {
if ('fly' in animal) {
animal.fly();
} else {
animal.swim();
}
}- 使用类型断言:
在某些情况下,你可能确定知道类型,可以使用类型断言:
type Result = string | number;
function processResult(result: Result) {
const stringResult = result as string;
console.log(stringResult.toUpperCase());
// 注意:这种方法不安全,如果类型猜测错误,可能导致运行时错误
}- 使用 switch 语句和可辨识联合:
对于具有共同属性的联合类型,可以使用 switch 语句:
interface Circle {
kind: 'circle';
radius: number;
}
interface Square {
kind: 'square';
sideLength: number;
}
type Shape = Circle | Square;
function getArea(shape: Shape) {
switch(shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.sideLength ** 2;
}
}- 使用条件类型(Conditional Types):
在泛型或高级类型操作中,可以使用条件类型:
type ExtractStringType<T> = T extends string ? T : never;
type NumberOrString = number | string;
type JustString = ExtractStringType<NumberOrString>; // 结果是 string这些方法让你可以在运行时或类型系统中确定联合类型的具体类型。选择哪种方法取决于你的具体需求和类型的结构。类型守卫通常是最安全和最常用的方法,因为它们提供了运行时的类型检查。