Typescript:允许泛型类型仅为带有';字符串';性质

Typescript:允许泛型类型仅为带有';字符串';性质,typescript,Typescript,我想知道在TS中是否可以强制泛型的属性类型。我只允许传递具有“string”属性的对象类型的泛型。例如,如果传递的泛型接口将包含数字或符号属性,则引发错误 以下是我尝试和评论的行为的一个例子: class Test<T extends {[key: string]: any}>{ private data: T; public getValue<K extends keyof T>(key: K): T[K] { return this.

我想知道在TS中是否可以强制泛型的属性类型。我只允许传递具有“string”属性的对象类型的泛型。例如,如果传递的泛型接口将包含数字或符号属性,则引发错误

以下是我尝试和评论的行为的一个例子:

class Test<T extends {[key: string]: any}>{
    private data: T;

    public getValue<K extends keyof T>(key: K): T[K] {
        return this.data[key];
     }
}

// the property is a string = ok
const okay = new Test<{ "aString": string }>();

// the property is a number = should raise an error
const shouldFail = new Test<{ 0: string }>();
类测试{
私人资料:T;
公共getValue(键:K):T[K]{
返回此.data[键];
}
}
//该属性是字符串=ok
const ok=新测试();
//属性为数字=应引发错误
const shouldFail=新测试();

如果对象有字符串索引,我们也可以按数字索引对象,因此编译器没有理由抛出错误编号。这是故意的

declare let skeys: { [key: string]: number }
let v1 = skeys[0] // number 
let v2 = skeys["0"] // number

declare let nkeys: { [key: number]: number }
let v3 = nkeys[0] // number 
let v4 = nkeys["0"] // error 


declare let snkeys: {
    [key: number]: number;
    [key: string]: string | number // The string index has to contain any value reuned by the number index
}
let v5 = snkeys[0] // number 
let v6 = snkeys["0"] // string| number 
如果对象包含任何非字符串键,我们可以使用条件类型强制执行错误。错误不会很漂亮,但它是可读的,可以完成工作:

class Test<T extends { [key: string]: any } & (keyof T extends string ? {} : "T must obnly have string keys") >{
    private data!: T;

    public getValue<K extends keyof T>(key: K): T[K] {
        return this.data[key];
    }
}

// the property is a string = ok
const okay = new Test<{ "aString": string }>();
// Error: Type '{ 0: string; }' does not satisfy the constraint '{ [key: string]: any; } & "T must only have string keys"'.
const shouldFail = new Test<{ 0: string }>();

相关:@bugs这是另一种情况,11315131不包括扩展另一个接口。+1我甚至建议:
类测试{
@FlavienVolken是的,那也行。.索引签名将有助于约束object@FlavienVolken添加了您的建议:)
class Test<T extends object & (keyof T extends string ? {} : "T must only have string keys") >{ }