是否可以将泛型类型限制为 TypeScript 中 keyof 的子集? [英] Is it possible to constrain a generic type to be a subset of keyof in TypeScript?
问题描述
在当前版本 (2.1) 的 TypeScript 中,我可以将泛型类的方法参数限制为泛型类型的属性.
In the current version (2.1) of TypeScript I can constrain a method argument on a generic class to be a property of the generic type.
class Foo<TEntity extends {[key:string]:any}> {
public bar<K extends keyof TEntity>(key:K, value:TEntity[K]) { }
}
在当前的类型系统中,是否有可能将键部分进一步限制为键值属于某种类型的子集?
Is it possible in the current type system to constrain the key part even further to be a subset where the value of the key is of a certain type?
我正在寻找的是与这个伪代码类似的东西.
What I'm looking for is something along the lines of this psuedo code.
class Foo<TEntity extends {[key:string]:any}> {
public updateText<K extends keyof TEntity where TEntity[K] extends string>(key:K, value:any) {
this.model[key] = this.convertToText(value);
}
}
编辑
为了澄清起见,我添加了一个更完整的示例来说明我要实现的目标.
For clarification I added a more complete example of what I'm trying to achieve.
type object = { [key: string]: any };
class Form<T extends object> {
private values: Partial<T> = {} as T;
protected convert<K extends keyof T>(key: K, input: any, converter: (value: any) => T[K])
{
this.values[key] = converter(input);
}
protected convertText<K extends keyof T>(key: K, input: any)
{
this.values[key] = this.convert(key, input, this.stringConverter);
}
private stringConverter(value: any): string
{
return String(value);
}
}
convertText
将给出一个错误,指出 Type 'string' 不可分配给 type 'T[K]'
.
convertText
will give an error saying that Type 'string' is not assignable to type 'T[K]'
.
给定
interface Foo {
s: string
n: number
}
编译器可以判断这会起作用
The compiler can tell that this will work
this.convert('s', 123, v => String(v));
这不会
this.convert('n', 123, v => String(v));
我希望我可以将 convertText
方法限制为值类型为 string
的键,以获得键参数的类型安全.
I'm hoping I can constrain the convertText
method to keys where the value is of type string
to get type safety on the key parameter.
推荐答案
这是可能的(此处使用非类示例).以下将确保 T[P]
是一个字符串.
It is possible (using a non-class example here). The following will ensure that T[P]
is a string.
function convertText<T extends {[key in P]: string }, P extends keyof T>(data: T, field: P & keyof T) {
// ...
}
想法是将 T
的类型缩小到仅在 P
中推断的字段,并设置您想要的确切类型,在本例中为 string代码>.
The idea is to narrow the type of T
to only the fields inferred in P
and set the exact type you want, in this case string
.
测试:
let obj = { foo: 'lorem', bar: 2 };
convertText(obj, 'foo');
convertText(obj, 'bar'); // fails with: Type 'number' is not assignable to type 'string'.
这篇关于是否可以将泛型类型限制为 TypeScript 中 keyof 的子集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!