【问题标题】:TS2322: Type '{ [x: string]: string; }' is not assignable to type 'Record '. Typescript GenericTS2322:类型'{ [x:字符串]:字符串; }' 不可分配给类型 'Record '。打字稿通用
【发布时间】:2020-11-15 07:30:22
【问题描述】:

我对 typescript Generic 有疑问

代码:

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: Type '{ [x: string]: string; }' is notassignable to type 'Record'。”在:

const error: ValidationError<S> = {
  [key]: 'error!',
};

有人可以描述为什么会发生错误以及如何解决它吗?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    这是一个棘手的问题。这就是我怀疑正在发生的事情。当您使用括号表示法创建具有动态键的对象时,我认为打字稿会自动假定该动态值的类型为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 和动态字段创建对象时,打字稿不会将其评估为键入 {[x: string]: string}

    为了使第二个解决方案更好一点,您可以编写一个辅助函数,例如:

    function createValidationError<S>(key: keyof S): ValidationError<S> {
        return Object.create({[key]: "error!"});
    }
    

    然后你可以直接调用它而不是在其他函数中构建对象。

    【讨论】:

    • Object.create 返回类型为any,tsc 将愉快地编译以下内容:const a: { [k in Key]: T[Key] } = Object.create({ random: 100, properties: 200 });
    猜你喜欢
    • 2016-10-25
    • 2021-11-05
    • 1970-01-01
    • 2019-02-05
    • 2021-11-10
    • 2022-01-17
    • 2020-02-07
    • 2019-07-12
    • 1970-01-01
    相关资源
    最近更新 更多