在 TypeScript 中,交叉类型和联合类型是两个非常重要和常用的类型。这两种类型都可以将多个类型组合成一个新的类型,但是它们的运作方式却有所不同。本文将详细介绍 TypeScript 中的交叉类型和联合类型,以及它们的用法和注意事项。
交叉类型
交叉类型可以让我们把多个类型组合成一个类型,用 & 符号连接多个类型即可。例如:
// www.javascriptcn.com code example
type Person = {
name: string;
age: number;
};
type Employee = {
company: string;
jobTitle: string;
};
type PersonAndEmployee = Person & Employee; // 交叉类型
const john: PersonAndEmployee = {
name: 'John Doe',
age: 30,
company: 'XYZ Inc.',
jobTitle: 'Software Developer'
};上述代码中,我们定义了 Person 和 Employee 两种类型,然后使用 & 符号连接它们,得到了一个新类型 PersonAndEmployee,表示既是 Person 又是 Employee 的类型。可以看到,我们成功创建了一个 PersonAndEmployee 对象,它同时包含 Person 和 Employee 的所有属性。
交叉类型有一个非常实用的场景,即在 TypeScript 中对多个对象进行合并。例如:
const person1 = { name: 'John', age: 30 };
const person2 = { city: 'New York', country: 'USA' };
const mergedPerson = { ...person1, ...person2 }; // 对象合并
console.log(mergedPerson); // { name: 'John', age: 30, city: 'New York', country: 'USA' }上述代码中,我们使用了对象的展开运算符 ... 对 person1 和 person2 进行合并,得到了一个新的对象 mergedPerson。这里的 mergedPerson 类型是交叉类型,同时包含了 person1 和 person2 的所有属性。这样的做法可以避免手动合并对象属性的麻烦和出错的可能性。
联合类型
联合类型可以让我们指定一个值可以是多种类型之一,用 | 符号连接多个类型即可。例如:
type Result = number | string;
function showResult(result: Result) {
console.log(`Result: ${result}`);
}
showResult(100); // Result: 100
showResult('success'); // Result: success上述代码中,我们定义了 Result 类型为 number | string,即可以是数字或字符串类型。然后我们定义了一个 showResult 函数,接收一个 Result 类型的参数并显示出来。在调用 showResult 函数时,我们分别传入了数字和字符串类型,因为它们都是 Result 类型的变量。
联合类型的另一个非常实用的场景是在 TypeScript 中实现方法重载。例如:
// www.javascriptcn.com code example
function convert(value: string): number; // 重载 1
function convert(value: number): string; // 重载 2
function convert(value: string | number): string | number { // 实现
if (typeof value === 'string') {
return Number(value);
} else {
return String(value);
}
}
console.log(convert('100')); // 100
console.log(convert(100)); // '100'上述代码中,我们定义了一个 convert 函数,该函数有两个重载,一个接收字符串类型的参数并返回数字类型,另一个接收数字类型的参数并返回字符串类型。最后我们在函数实现中,使用一个联合类型参数 value: string | number 来统一处理不同的情况。
注意事项
在使用交叉类型和联合类型时,我们需要注意以下几点:
- 交叉类型只能用于类型的合并,不能用于运行时的操作。
- 联合类型必须确保每一个类型都包含共有的属性或方法。
- 联合类型无法通过类型推断来实现类型保护,需要手动进行类型判断和转换。
下面是一个示例代码,它演示了如何使用联合类型和类型保护来处理多个类型的变量:
// www.javascriptcn.com code example
type Bird = {
hasFeathers: true;
canFly: true;
};
type Fish = {
hasFeathers: false;
canSwim: true;
};
function move(animal: Bird | Fish) {
if ('canFly' in animal) {
console.log('The bird is flying');
} else {
console.log('The fish is swimming');
}
}
const bird: Bird = { hasFeathers: true, canFly: true };
const fish: Fish = { hasFeathers: false, canSwim: true };
move(bird); // The bird is flying
move(fish); // The fish is swimming上述代码中,我们定义了 Bird 和 Fish 两种类型,然后定义了一个 move 函数,接收一个 Bird | Fish 类型的参数并根据不同的类型输出不同的内容。在调用 move 函数时,我们先传入一个 Bird 类型和一个 Fish 类型的变量,然后得到了正确的输出结果。
综合来看,交叉类型和联合类型是 TypeScript 中非常重要和常用的类型,可以帮助我们更加灵活地处理多个类型之间的关系。同时,我们需要注意它们的用法和注意事项,确保代码能够正确、可靠地运行。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d7e604a941bf7134e20246