ts 之 函数参数双向协变
时间: 2023-07-12 17:23:08 浏览: 126
在 TypeScript 中,函数参数双向协变是指当一个函数的参数类型是一个联合类型时,传入的实参的类型可以是联合类型中的任意一种类型,同时函数返回值的类型也可以是联合类型中的任意一种类型。这个特性可以让我们更加灵活地使用函数,避免代码重复。
举个例子,假设我们有一个函数 `pick`,用于从一个对象中选取指定的属性并返回一个新的对象。函数定义如下:
```typescript
function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
const ret = {} as Pick<T, K>
keys.forEach(key => {
ret[key] = obj[key]
})
return ret
}
```
其中,`Pick` 是 TypeScript 内置的一个类型,用于从一个对象中选取指定的属性构造一个新的对象类型。现在我们想要使用这个函数来选取一个人的姓名和年龄属性,我们可以这样调用:
```typescript
interface Person {
name: string
age: number
}
const john: Person = { name: 'John', age: 18 }
const nameAndAge = pick(john, 'name', 'age')
```
这个例子中,我们传入了一个 `Person` 类型的对象 `john`,同时指定了要选取的属性为 `'name'` 和 `'age'`。根据函数定义,函数返回值的类型应该是 `Pick<Person, 'name' | 'age'>`,也就是 `{ name: string, age: number }` 类型。这个例子是完全符合预期的。
但是,如果我们把 `john` 对象的类型改为一个联合类型:
```typescript
const john: Person | { name: string, age: string } = { name: 'John', age: 18 }
```
这个时候,我们仍然可以调用 `pick` 函数,并且传入的参数类型为 `Person | { name: string, age: string }`,也就是 `john` 对象的类型。此时,函数返回值的类型应该是 `Pick<Person | { name: string, age: string }, 'name' | 'age'>`,也就是 `{ name: string, age: string } | { name: string, age: number }` 类型。这个类型是一个联合类型,表示返回值可以是两种不同的类型之一。
总之,函数参数双向协变可以让我们更加灵活地使用函数,但是在使用过程中也需要注意参数类型的限制,避免出现类型错误。
阅读全文