TypeScript索引签名类实现

TypeScript索引签名类实现,typescript,Typescript,考虑以下代码段: export interface IProduct { [key: string]: number | boolean; } export class Product implements IProduct { b: number; c: boolean; } 我希望TypeScript能够理解以下内容: 嘿,IPProduct接口可以是任何类型的对象,具有任何 可由以下类型之一指定的字段数: 数字或布尔值。现在是实现这个接口的类 基本上可以包含完全

考虑以下代码段:

export interface IProduct {
    [key: string]: number | boolean;
}

export class Product implements IProduct {
    b: number;
    c: boolean;
}
我希望TypeScript能够理解以下内容:

嘿,IPProduct接口可以是任何类型的对象,具有任何 可由以下类型之一指定的字段数: 数字或布尔值。现在是实现这个接口的类 基本上可以包含完全相同的字段变量

不幸的是,上面的代码给了我一个错误,该类没有正确实现接口,迫使我将索引类型重新类型化为类本身:

export class Product implements IProduct {
    [key: string]:  number | boolean;
    b: number;
    c: boolean;
}
但老实说,我的期望是我可以只声明类字段,只要它们符合接口声明契约,我就不会得到如下错误:

export class Product implements IProduct {
    b: number;
    c: boolean;
    a: string /* Gives erorr, since string is not allowed index type */
}

关于如何绕过这一点或仅凭我的理解,任何想法都是错误的?

您可以创建一个强制执行所需约束的类型,但它必须是映射类型:

export type IProduct<T> = Record<keyof T, number | boolean>
// Or, same effect but using the actual mapped type
// export type IProduct<T> = {
//    [P in keyof T]: number | boolean;
//}

export class Product implements IProduct<Product> {
    b: number;
    c: boolean;
}
typescript抱怨的原因是接口索引签名允许您使用任何字符串进行索引,但该类只有特定的键。如果您的类实际上可以有任何键,那么它应该具有索引签名以使其显式

编辑

不同版本,其中接口的泛型类型参数是接口将具有的键:

export type IProduct<T extends PropertyKey> = Record<T, number | boolean>

export class Product implements IProduct<keyof Product> {
    b: number;
    c: boolean;
}
let o: IProduct<'c' | 'b'> = new Product();

您可以创建强制执行所需约束的类型,但必须是映射类型:

export type IProduct<T> = Record<keyof T, number | boolean>
// Or, same effect but using the actual mapped type
// export type IProduct<T> = {
//    [P in keyof T]: number | boolean;
//}

export class Product implements IProduct<Product> {
    b: number;
    c: boolean;
}
typescript抱怨的原因是接口索引签名允许您使用任何字符串进行索引,但该类只有特定的键。如果您的类实际上可以有任何键,那么它应该具有索引签名以使其显式

编辑

不同版本,其中接口的泛型类型参数是接口将具有的键:

export type IProduct<T extends PropertyKey> = Record<T, number | boolean>

export class Product implements IProduct<keyof Product> {
    b: number;
    c: boolean;
}
let o: IProduct<'c' | 'b'> = new Product();

泰坦:@Tomas:我在这附近花了很多时间。泰坦:@Tomas:我在这附近花了很多时间: