在 TypeScript 的当前版本 (2.1) 中,我可以将泛型类的方法参数限制为泛型类型的属性。
class Foo<TEntity extends {[key:string]:any}> {
public bar<K extends keyof TEntity>(key:K, value:TEntity[K]) { }
}
在当前的类型系统中是否可以将键部分进一步限制为键值属于特定类型的子集?
我正在寻找的是与此伪代码类似的东西。
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);
}
}
编辑
为了清楚起见,我添加了一个更完整的示例来说明我要实现的目标。
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' is not assignable to type 'T[K]'
。
给定
interface Foo {
s: string
n: number
}
编译器可以判断这是可行的
this.convert('s', 123, v => String(v));
这不会
this.convert('n', 123, v => String(v));
我希望我可以将 convertText
方法限制为值为 string
类型的键,以获得键参数的类型安全。
最佳答案
这是可能的(这里使用一个非类的例子)。以下将确保 T[P]
是一个字符串。
function convertText<T extends {[key in P]: string }, P extends keyof T>(data: T, field: P & keyof T) {
// ...
}
想法是将 T
的类型缩小为仅在 P
中推断的字段,并设置您想要的确切类型,在本例中为 string
.
测试:
let obj = { foo: 'lorem', bar: 2 };
convertText(obj, 'foo');
convertText(obj, 'bar'); // fails with: Type 'number' is not assignable to type 'string'.
关于typescript - 是否可以将泛型类型限制为 TypeScript 中 keyof 的子集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41687152/