需要声明一个对象类型。得到下面提到的错误:
let array = ["£179.95", "£199.95", "£89.95"]
let sum = array.compactMap { Double($0.replacingOccurrences(of: "£", with: "")) }
.reduce(0.0, { $0 + $1 })
print(sum) // 469.84999999999997
TypeScript抛出以下错误:
类型'{[x:字符串]:{颜色:字符串}}'缺少类型'记录'中的以下属性:奔驰,奔驰轿车,奔驰车舱盖
答案 0 :(得分:3)
您的代码有错误,KEY_MAP
中的值实际上与CarKeys
中指定的值不匹配。另外,carType
中的分号必须是逗号。
要解决当前的问题,可以使用as const
。在您的代码中,KEY_MAP
的解析类型为:
const KEY_MAP: {
mercedes: string;
mercedes_sedan: string;
mercedes_hatch: string;
}
像这样指定它:
const KEY_MAP = {
mercedes: 'mercedes',
mercedes_sedan: 'mercedes_sedan',
mercedes_hatch: 'mercedes_hatch'
} as const;
然后解析的类型将是:
const KEY_MAP: {
readonly mercedes: "mercedes";
readonly mercedes_sedan: "mercedes_sedan";
readonly mercedes_hatch: "mercedes_hatch";
}
应该编译哪个。
答案 1 :(得分:3)
两件事,首先是您写了type CarKeys = "mercedes" | "mercedes_sedan" | "mercedes_hatch"
,都带有下划线,但是KEY_MAP
中的值带有连字符,这可能与您想匹配的不匹配解决。
第二,默认情况下,TS会推断typeof KEY_MAP
为{ mercedes: string; ... }
而不是{ mercedes: "mercedes", ... }
。
这意味着typeof [KEY_MAP.mercedes]
实际上是string
,而不是"mercedes"
字符串文字,因此typeof carType
实际上是{ [key: string]: Car }
,这就是错误的原因。
要解决此问题,您可以在as const
的末尾添加KEY_MAP
:
const KEY_MAP = {
mercedes: 'mercedes',
mercedes_sedan: 'mercedes-sedan',
mercedes_hatch: 'mercedes-hatch'
} as const;
或者,您也可以将其变成enum
enum KEY_MAP {
mercedes = 'mercedes',
mercedes_sedan = 'mercedes-sedan',
mercedes_hatch ='mercedes-hatch'
}
答案 2 :(得分:2)
首先,在使用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
字符串文字类型不应被视为“魔术字符串”,因为编译器会监视它,并键入safe。我们不需要创建一些中间结构即可直接使用它。
最后一点同样重要。您可以通过为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
中的确切单个项目作为键和值。