从模板中排除属性

  • 本文关键字:排除 属性 typescript
  • 更新时间 :
  • 英文 :


我有这样的代码,可以从接口中排除属性

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
interface MyType {
id: string
timeout: number
delta: number
}
let value: Omit<MyType, 'id'> = {
timeout: 10,
delta: 5,
}

这还可以,但我不能将属性从泛型类型中排除,比如:

function foo<T>(x: T) {
let value: Omit<T, 'id'> = {
timeout: 10,
delta: 5,
}
}
foo<MyType>({ timeout: 10, delta: 5 })

现在我收到错误消息Type '"id"' does not satisfy the constraint 'keyof T'我做错了什么?

这是因为编译器不能仅根据函数声明来检查类型T是否实际具有属性id。我们可以添加一个约束来告诉编译器将要传递的内容将具有id属性:

function foo<T extends { id: string }>(x: Omit<T, 'id'>) {
let value: Omit<T, 'id'> = x;
}
foo<MyType>({ timeout: 10, delta: 5 })

您会注意到,我没有用对象文字初始化函数内的value变量,这是因为如果您不知道完整类型,就无法创建对象文字。关于T,我们只知道它具有和id属性,对于T具有的其他属性,它们具有什么类型以及是否需要它们,我们一无所知。

如果你真的需要在函数中初始化一个泛型类型的变量,唯一(unsafe(的方法是使用类型断言:

function foo<T extends MyType>(x: Omit<T, 'id'>) {
let value = {
timeout: 10,
delta: 5,
} as unknown as Omit<T, 'id'> // replace unknown with any for ts before 3.0
}

最新更新