typescript - 在 typescript 中输入接收对象键值对的回调

标签 typescript typescript-typings

我在 typescript 4.0.5 中编写了一个函数,它运行一个对象并为每个属性执行给定的回调,类似于 array.forEach (见下文)。 如果在 tsconfig 中设置了 noImplicitAny: true,则只有所有属性共享相同类型时,该函数的类型才似乎有效。

export function forEachKey<T extends Object>(obj: T, cb: (key: Extract<keyof T, string>, value: T[keyof T]) => void): void {
  for (const k in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, k)) {
      cb(k, obj[k]);
    }
  }
}

以下示例没有错误:

interface TestNumber {
  a: number;
  b: number;
}
const t1Nr: TestNumber = { a: 1, b: 2 };
const t2Nr: TestNumber = { a: 3, b: 4 };
forEachKey(t1Nr, (key, value) => {
  t2Nr[key] = value;
});

但是一旦存在不同类型的属性:

interface TestMixed {
  a: number;
  b: string;
}
const t1: TestMixed = { a: 1, b: '2' };
const t2: TestMixed = { a: 1, b: '2' };
forEachKey(t1, (key, value) => {
  t2[key] = value;    // error
});

我收到错误:

TS2322:输入“字符串|” number” 不可分配给类型“never”。类型“string”不可分配给类型“never”。

据我所知,我必须将 value 的类型声明为 T[key] 但我找不到方法来做到这一点。

有人知道如何修复打字吗? 提前致谢


编辑:

在 Aleksey 的回答使用这个简单的示例后,我尝试将该示例转换为我当前的实现。 我们有一个如下所示的类:


class TestMixed2Class implements TestMixed {
  constructor (public a: number = 1, public b: string = '2', public c: number = 3) {}

  setParams(params: TestMixed) {
    forEachKey(params, (key, value) => this[key] = value);   // error
  }
}

这会导致错误

TS2322: Type 'TestMixed[K]' is not assignable to type 'this[K]'.
   Type 'TestMixed' is not assignable to type 'this'.
     'this' could be instantiated with an arbitrary type which could be unrelated to 'TestMixed'.
       Type 'TestMixed[K]' is not assignable to type 'never'.
         Type 'string | number' is not assignable to type 'never'.
           Type 'string' is not assignable to type 'never'.

是否还有一种方法可以在这里实现有效的输入?

最佳答案

您可以在 key 的内部函数中引入泛型类型参数,这样 Typescript 将能够匹配 keyvalue:

function forEachKey<T extends object>(obj: T, cb: <K extends keyof T>(key: K, value: T[K]) => void): void {
  for (const k in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, k)) {
      cb(k, obj[k]);
    }
  }
}

Playground

关于typescript - 在 typescript 中输入接收对象键值对的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66013341/

相关文章:

typescript :使用 `enum` 值作为 `type`

javascript - 输入 onChange w/React & TypeScript 错误 : jsx no-lambda no-bind

typescript - TypeScript 中的联合类型——我能做到吗?

angular - 比较 2 个输入字段的值以通过模板验证 Angular 7 中的表单

typescript - VSC 中的 ESLint 不适用于 .ts 和 .tsx 文件

typescript - 如何从给定路径创建对象?

mysql - 如何将 Sequelize 关联添加到模型中

typescript - 如何为 TypeScript 编译器排除 *.d.ts 文件?

javascript - 在 Typescript 中输入可选的可调用装饰器

typescript - 将 globalize 与 webpack 2 和 typescript 结合使用