缩小分配失败:类型不可分配为“从不”

问题描述 投票:0回答:1

我想动态修改对象中的值:

interface type {
  id: number;
  name: string;
}
const formFields: (keyof type)[] = ['id', 'name']
let test: type = {
  id: 0,
  name: `name`
}
let data: string[] = ['1', 'Name']
for (let i = 0; i < data.length; i++) {
  const field = formFields[i];
  if (typeof test[field] === 'number') {
    test[field] = Number(data[i]);
  } else if (typeof test[field] === 'string') {
    test[field] = data[i];
  }
}

但我无法避免这个错误:

Type 'number' is not assignable to type 'never'.(2322)

虽然不影响实际操作。

typescript
1个回答
0
投票

在 JS/TS 中,属性可能有 getter 和 setter,并且它们的类型可能不同。您检查 getter 返回的类型,但 setter 可能接受不同的类型。看这个例子:

const obj = {
  val: "",
  get prop(): string {
    return this.val;
  },
  set prop(val: number) {
    this.val = val.toString()
  },
}

// The following assignment does not compile:
if (typeof obj.prop === "string") { // here prop looks like a string property
  obj.prop = "str" // but here prop is already a number property
}

这个例子应该可以阐明为什么 TS 会有这样的行为。


下面有两个选项供您解决问题。

第一个选项保持逻辑不变并绕过 TS 错误:

interface type {
  id: number;
  name: string;
}
const formFields: (keyof type)[] = ['id', 'name']
let test: type = {
  id: 0,
  name: `name`
}
let data: string[] = ['1', 'Name']
for (let i = 0; i < data.length; i++) {
  const field = formFields[i];
  if (typeof test[field] === 'number') {
    setTestField(field, Number(data[i]))
  } else if (typeof test[field] === 'string') {
    setTestField(field, data[i])
  }
}
function setTestField<T extends keyof type>(key: T, value: type[T]): void {
  test[key] = value
}

第二个选项是稍微重写你的逻辑:

interface type {
  id: number;
  name: string;
}
const formFields: (keyof type)[] = ['id', 'name']
let test: type = {
  id: 0,
  name: `name`
}
let data: string[] = ['1', 'Name']
for (let i = 0; i < data.length; i++) {
  const field = formFields[i];
  switch (field) {
    case 'id':
      test.id = Number(data[i]);
      break;
    case 'name':
      test.name = data[i]
      break;
  }
}

也许其中之一适合您的情况。

© www.soinside.com 2019 - 2024. All rights reserved.