本文介绍了Typescript编译器永远不会错误:键入'string |数字"不能分配给“从不"类型.不能将类型“字符串"分配给类型“从不"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我得到的一段代码:

Here is a piece of code i got:

interface Obj {
  a: number
  b: string
}

const obj: Obj = {
  a: 1,
  b: 'hi'
}

function fn(key: keyof Obj, value: Obj[keyof Obj]) {
  let foo = obj[key]
  obj[key] = value
}

fn("a", 2)

所以我想做的是,我希望函数 fn()能够更新对象 obj 属性,该函数的第一个参数是 obj 拥有的键(在 Obj 接口中定义),第二个参数是您想要赋予该键的值.

So what i want to do is, i want the function fn() to be able to update the object obj properties, the first argument of this function is any key that obj has(defined in Obj interface), and the second argument is the value you wanna give to that key.

但是,在此行的 obj [key] = value 中出现错误的打字稿弹出窗口是

However, the typescript popup with an error in the obj[key] = value this line, which is:

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

以下是屏幕截图:

如果您将鼠标悬停在变量 foo (图片中的第13行)上,就会发生一个奇怪的事情,它说:

And a strange thing happens here, if you hover to the variable foo(which is line 13 in the picture), it says:

let foo: string | number

表示 obj [key] 的类型为 string |数字,但错误显示 obj [key] 类型为从不.

which means, obj[key]'s type is string | number, but the error says obj[key] type is never.

然后我又得到了解决该问题的一段代码:

Then i got another piece of code which solves this problem:

interface Obj {
  a: number
  b: string
}

const obj: Obj = {
  a: 1,
  b: 'hi'
}

function fn<K extends keyof Obj>(key: K, value: Obj[K]) {
  obj[key] = value
}

fn("a", 2)

顺便说一句,所有代码均以打字稿 3.7.5 版本进行了测试.

BTW, all the code are tested in typescript 3.7.5 version.

我不是英语母语人士,希望我能清楚地解释我的困惑.

I am not a native English speaker, hope i explained my confusion clearly.

推荐答案

该错误怎么办,这是因为 Obj的关键字可能是'a'类型为 number string 的"b" .在表达式 obj [key] 中,编译器不知道属性类型,它也可能是 number string ,因此不允许这样的任务.此处是相同的问题.您可以在此处中找到说明,请参见修复将不正确的内容写入索引访问类型.

What about the error, it's because keyof Obj might be "a" or "b" which have type number or string. In the expression obj[key] the compiler doesn't know the property type, it might be number or string as well, so it disallows such assignment. Here is the same question. And you can find the explanation here, see Fixes to unsound writes to indexed access types.

对于通用函数, K扩展了Obj的键表示 K 类型可以是"a" "b'" 也是如此,但是当您调用函数 fn("a",2)时,您会隐式地将 K 设置为"a".,编译器从第一个参数推断 K 类型.因此,现在,在调用上下文中, key 具有"a" 类型,而 Obj [K] number ,因此分配变得正确.

In case of the generic function K extends keyof Obj means that K type can be "a" or "b" as well, but when you call the function fn("a", 2) you implicitly set K to "a", the compiler infers K type from the first argument. So now, inside the call context key has "a" type and Obj[K] is number, hence the assignment becomes correct.

我只是试图向我的妻子(不是程序员)解释这种区别:)我认为这也可能有帮助:

I just tried to explain the difference to my wife, who isn't a programmer :) I think it might be helpfull too:

通用功能:在这种情况下,您睁开了眼睛,可以选择要吃的蛋糕,但仍然有两种选择:樱桃或香蕉.现在,如果您选择并品尝了香蕉蛋糕,则可以说多么美味的香蕉蛋糕!".

Generic function: In this case you eyes are open and you can choose the cake you want to eat, but you still have two choices: cherry or banana. Now, if you've chosen the banana cake and tasted it, you can say "What a delicious banana cake!".

这篇关于Typescript编译器永远不会错误:键入'string |数字"不能分配给“从不"类型.不能将类型“字符串"分配给类型“从不"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 07:03
查看更多