说我有一个函数,该函数采用某种具有name
属性的对象。它不关心对象上的其他属性,只关心它的类型为name
的{{1}},因此它应该接受符合此条件的任何对象类型。
是否有定义这种类型的简单方法?我最接近的是扩展由string
构造的类型,但这似乎有点不雅致:
Record
答案 0 :(得分:2)
您不需要为此做任何特殊的事情。这将定义必需的属性:
interface ThingWithName {
name: string
}
function greet(thing: ThingWithName) {
return `hello, ${thing.name}`
}
greet({name: ''}) // fine
let x = {name: '', age: 27};
greet(x) // also fine
您可能要面对的是多余的属性检查,当对象文字直接分配给特定的类型引用时,多余的属性检查会禁止额外的属性。因此,在上面的代码中:greet({name: '', age: 27})
将是一个错误。
您可以通过以下几种方法之一来解决此限制。
最安全的方法是使用通用类型参数:
interface ThingWithName {
name: string
}
function greet<T extends ThingWithName>(thing: T) {
return `hello, ${thing.name} ${thing.age}` // age is invalid
}
greet({name: ''}) // fine
greet({name: '', age: 27}) // also fine
如果您希望能够使用string
索引到对象中,那么您发现扩展记录的解决方案是可以的(使用索引签名可以达到相同的效果):
interface ThingWithName extends Record<string, any> {
name: string
}
function greet(thing: ThingWithName) {
return `hello, ${thing.name} ${thing.age}` // age is valid, so be ware you can dot into thing with any prop
}
greet({name: ''}) // fine
greet({ }) // err
greet({name: '', age: 27}) // also fine