typescript - 是否可以将泛型类型限制为 TypeScript 中 keyof 的子集?

标签 typescript typescript2.0

在 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);
    }
}

Demo on typescriptlang.org

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/

相关文章:

javascript - 如何对数组中的每个文件发出 POST 请求

angular - 在 Visual Studio 2015 中从类型转换为@types

javascript - 如何在 Typescript 中为 Map 的类型别名定义索引签名?

typescript - 如何使用 jsdom 和 typescript 防止 "Property ' .. .' does not exist on type ' Global'"?

typescript - 使用 System.js 在 TypeScript 中加载模块

jquery - 运行 'ng test'命令时找不到JQuery

typescript - 如何用 `object` 替换 `Record<string, unknown>` ?

javascript - 更改 NativeScript TabView 默认行为

typescript - 如何从联合中提取单一类型?

typescript - gulp-typescript 和 typescript 的新@types 打字?