[英]Is it possible to constrain a generic type to be a subset of keyof in 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. 在TypeScript的当前版本(2.1)中,我可以将泛型类的方法参数约束为泛型类型的属性。
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);
}
}
EDIT 编辑
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);
}
}
Demo on typescriptlang.org 在typescriptlang.org上演示
convertText
will give an error saying that Type 'string' is not assignable to type 'T[K]'
. convertText
将给出一个错误,指出convertText
Type 'string' is not assignable to type 'T[K]'
。
Given 特定
interface Foo {
s: string
n: number
}
The compiler can tell that this will work 编译器可以告诉它这将工作
this.convert('s', 123, v => String(v));
and this will not 这不会
this.convert('n', 123, v => String(v));
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. 我希望我可以将
convertText
方法约束到值为string
类型的键,以获得key参数的类型安全性。
It is possible (using a non-class example here). 这是可能的(在这里使用非类示例)。 The following will ensure that
T[P]
is a string. 以下将确保
T[P]
是一个字符串。
function convertText<T extends {[key in P]: string }, P extends keyof T>(data: T, field: P & keyof T) {
// ...
}
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
. 我们的想法是将
T
的类型缩小到仅在P
推断出的字段,并设置所需的确切类型,在本例中为string
。
Test: 测试:
let obj = { foo: 'lorem', bar: 2 };
convertText(obj, 'foo');
convertText(obj, 'bar'); // fails with: Type 'number' is not assignable to type 'string'.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.