1. 接口与类型别名兼容性处理
- 基本规则:在TypeScript中,接口与类型别名在兼容性检查时,主要关注结构的兼容性,即成员的类型是否匹配,而不关注它们的声明方式。只要两个类型具有兼容的成员,它们就是兼容的。
- 代码示例:
// 接口定义
interface Point1 {
x: number;
y: number;
}
// 类型别名定义
type Point2 = {
x: number;
y: number;
};
let p1: Point1;
let p2: Point2;
p1 = p2; // 可以赋值,因为结构兼容
p2 = p1; // 同样可以赋值
2. 函数参数类型兼容性判断依据
- 基本规则:函数参数类型兼容性是协变的,即赋值给目标函数的源函数的参数类型可以是目标函数参数类型的子类型。也就是说,如果目标函数接受一个更宽泛的类型,那么源函数可以接受一个更具体的类型。
- 代码示例:
function greet1(person: { name: string }) {
console.log(`Hello, ${person.name}!`);
}
function greet2(person: { name: string; age: number }) {
console.log(`Hello, ${person.name} who is ${person.age} years old!`);
}
let g1: typeof greet1;
let g2: typeof greet2;
g1 = greet2; // 可以赋值,因为greet2的参数类型是greet1参数类型的子类型
// g2 = greet1; // 报错,因为greet1的参数类型不是greet2参数类型的子类型
3. 函数返回值类型兼容性判断依据
- 基本规则:函数返回值类型兼容性是逆变的,即赋值给目标函数的源函数的返回值类型可以是目标函数返回值类型的超类型。也就是说,如果目标函数返回一个更具体的类型,那么源函数可以返回一个更宽泛的类型。
- 代码示例:
function getAnimal1(): { legs: number } {
return { legs: 4 };
}
function getAnimal2(): { legs: number; wings: number } {
return { legs: 2, wings: 2 };
}
let a1: typeof getAnimal1;
let a2: typeof getAnimal2;
a2 = getAnimal1; // 可以赋值,因为getAnimal1的返回值类型是getAnimal2返回值类型的超类型
// a1 = getAnimal2; // 报错,因为getAnimal2的返回值类型不是getAnimal1返回值类型的超类型