[英]can TypeScript restrict keyof to a list of properties of a particular type?
so, I want to write a generic method.所以,我想写一个泛型方法。 For the sake of the question, let's say I want to concatenate 2 string properties from 2 different objects of the same type.
为了这个问题,假设我想连接来自相同类型的 2 个不同对象的 2 个字符串属性。
function concat<T>(target1: T, target2: T, key: keyof T): string {
return target1[key] + target2[key];
}
The above fails to compile because the compiler has no indication that I want to restrict key
to only be the list of properties of type string
.以上无法编译,因为编译器没有表明我想将
key
限制为仅是string
类型的属性列表。
Is this not currently supported in TypeScript?这在 TypeScript 中目前不支持吗?
I know I can do runtime checks, but I want compile-time checks for this one.我知道我可以进行运行时检查,但我想要对此进行编译时检查。
You want a three parameter generic here.你想要一个三参数泛型这里。 One for each input, and one for the key.
每个输入一个,一个键。
type CommonKey<A, B> = keyof A & keyof B
function concat<A, B, K extends CommonKey<A, B>>(
target1: A,
target2: B,
key: K
): string {
return `${target1[key]}${target2[key]}`
}
This defines the key as both a key of A and B, meaning that it must satisfy both.这将密钥定义为 A 和 B 的密钥,这意味着它必须同时满足两者。
To constrain it further to only string values, you need to use a mapped type with a condition to test for its type.要将其进一步限制为仅字符串值,您需要使用带有条件的映射类型来测试其类型。
// This type returns all keys that have a value of type string
type StringKeyOf<T> = {
// for all keys in T
[K in keyof T]:
// if the value of this key is a string, keep it. Else, discard it
T[K] extends string ? K : never
// Get the union type of the remaining values.
}[keyof T]
// Only allow common keys of both objects.
type CommonKey<A, B> = StringKeyOf<A> & StringKeyOf<B>
function concat<
A,
B,
K extends CommonKey<A, B>
>(target1: A, target2: B, key: K): string {
return `${target1[key]}${target2[key]}`
}
Now this will give a type error, because age
is a number.现在这将给出一个类型错误,因为
age
是一个数字。
concat(
{ name: 'a', age: 12 human: 'maybe?' },
{ name: 'b', age: 8, dog: true },
'age' // Type error
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.