typescript - TS2322:类型'{ [x:字符串]:字符串;}' 不可分配给类型 'Record '。打字稿通用
问题描述
我有打字稿通用的问题
代码:
type ValidationError<S> = Record<keyof S, string>;
function validateType<S>(
key: keyof S,
value: string,
type: FieldType | FieldType[],
errors: ValidationError<S>[],
): void {
switch (type) {
case 'email': {
if (!validator.isEmail(value)) {
const error: ValidationError<S> = {
[key]: 'error!',
};
errors.push(error);
}
}
}
}
但是我有打字稿错误“TS2322:类型'{ [x:字符串]:字符串;}'不可分配给类型'记录'。” 在:
const error: ValidationError<S> = {
[key]: 'error!',
};
有人可以描述为什么会发生错误以及如何解决它吗?
解决方案
这是一个棘手的问题。这就是我怀疑正在发生的事情。当您使用括号表示法创建具有动态键的对象时,我认为 typescript 会自动假定该动态值是 type string
。所以当你这样做时:
const error = {[key]: "something"} /// type => {[x: string]: string};
而不是写类似的东西
const error = {something: "something"} /// type => {something: string} for example
我找到了两个你可以尝试的工作,这是第一个:
const error = {
[key]: "error!"
} as ValidationError<S>
这将使错误消失,但您在这里进行类型转换,因此您断言这是正确的类型。Typescript 阅读并信任您。
第二种解决方法
const error: ValidationError<S> = Object.create({[key]: "error!"})
在这里,您不再强制转换这是一个加号,但您必须使用Object.create
它不如使用文字好。我认为这可行的原因是因为在使用 Object.create 和动态字段创建对象时,打字稿不会将其评估为 type {[x: string]: string}
。
为了使第二个解决方案更好一点,您可以编写一个辅助函数,例如:
function createValidationError<S>(key: keyof S): ValidationError<S> {
return Object.create({[key]: "error!"});
}
然后你可以直接调用它,而不是在其他函数中构建对象。