首先,在使用 TypeScript 时,您不需要使用 Key -> Value map + String 文字类型。您可以选择两者之一,因为它将确保类型安全。使用 Enum 代替标准 JS 对象的方法也更合适,因为它可以解决一种语言结构中的值和类型。考虑仅使用 Enum 的解决方案:
interface Car { color: string; }
enum KEY_MAP {
mercedes = 'mercedes',
mercedes_sedan = 'mercedes_sedan',
mercedes_hatch = 'mercedes_hatch'
}
const carType: Record<KEY_MAP, Car> = {
[KEY_MAP.mercedes]:{ color: 'red'},
[KEY_MAP.mercedes_sedan]: {color: 'yellow'},
[KEY_MAP.mercedes_hatch]: {color: 'black'}
}
仅使用字符串文字的解决方案也是完全有效且类型安全的。考虑:
type CarKeys = "mercedes" | "mercedes_sedan" | "mercedes_hatch";
interface Car { color: string; }
const carType: Record<CarKeys, Car> = {
mercedes:{ color: 'red'},
mercedes_sedan: {color: 'yellow'},
mercedes_hatch: {color: 'black'}
} // carType cannot be created with wrong key or value type
字符串文字类型不应被视为“魔术字符串”,因为它被编译器监视并且类型安全。我们不需要创建一些中间结构来直接使用它。
最后一点也很重要。您可以通过为 KEY_MAP 指定正确的类型来直接修复您的实现。
type CarKeys = "mercedes" | "mercedes_sedan" | "mercedes_hatch";
interface Car { color: string; }
const KEY_MAP: { [P in CarKeys]: P } = { mercedes: 'mercedes', mercedes_sedan: 'mercedes_sedan', mercedes_hatch: 'mercedes_hatch'};
const carType:Record<CarKeys, Car> = {
[KEY_MAP.mercedes]:{ color: 'red'},
[KEY_MAP.mercedes_sedan]: {color: 'yellow'},
[KEY_MAP.mercedes_hatch]: {color: 'black'}
}; // no issues
核心是{ [P in CarKeys]: P }。我们是说我们的对象具有来自CarKeys 的确切单个项目作为键和值。