虽然您不能直接使用除 string 或 number 之外的任何东西作为索引签名中的键类型(并且您对 OFoo 的定义会导致您出现这种情况的错误),但您可以 使用mapped types 将键限制为string 的子类型。由于TFoo,又名keyof Foo,是string 的子类型,您可以使用如下映射类型:
type OFoo = { [K in TFoo]: any };
请注意,映射类型的语法与常规索引签名的语法不同。上面的TFoo 对应于允许键的类型,在您的情况下只是"a",但也可以是字符串文字的联合,如"a"|"b"|"c",甚至string。而上面的K 是一个参数,对应于每个属性的键的type。 (您并不真正关心K,因为每个属性value 的类型是any,与K 无关,但您可以使用K 来挑选如果您愿意,可以使用特定属性。)无论如何,让我们使用它:
let obj: OFoo = { a: 1 }; // okay
let obj = { }; // error, property 'a' is missing
let obj = { c: 1 }; // error, excess property 'c'
顺便说一句,我可能会使用内置标准库类型Record<K,T>,它的定义如下:
type Record<K extends string, T> = {
[P in K]: T
}
或者,您可以认为:“Record<K, T> 是一个对象,其中每个键都在 K 中,每个值都是 T”。对你来说,K 是 TFoo,T 是 any:
type OFoo = Record<TFoo, any>; // same thing
希望有所帮助;祝你好运!