你可以做这个函数
generic
function getFirstLetters<T extends Record<keyof T, string>>(obj: T): string[] {
return Object.keys(obj).map(key => obj[key][0]); // error
}
但是编译器(正确地)抱怨它不知道什么
obj[key]
可能是。毕竟
已知的
钥匙
T
是
string
-值,但TypeScript中的类型不是
exact
. 类型值
{foo: string}
可能有任意数量的额外属性。我们知道
foo
财产是一种财富
一串
,但据我们所知,它可能有一个
bar
那是一个
number
如果您确定只将完全相同的类型传递给
getFirstLetters
type assertion
function getFirstLetters<T extends Record<keyof T, string>>(obj: T): string[] {
// no error now
return (Object.keys(obj) as (Array<keyof T>)).map(key => obj[key][0]);
}
getFirstLetters(someData); // no error
它将拒绝具有已知属性的值,而这些属性的值不是
getFirstLetters({a: "a", b: 23}); // error on b, not a string
但请记住,您可以向它传递一些具有未知非字符串属性的内容,这些内容在运行时会导致问题:
const whoopsie: SomeData = Object.assign({}, someData, { oops: null });
// whoopsie is a SomeData with an extra "oops" property that the
// compiler has explicitly forgotten about
getFirstLetters(whoopsie); // no compiler error
// but calls null[0] at runtime and explodes!! ð¥