Typescript编译器从不错误:Type' string |号码'不能分配给'从不'类型.输入' string'不能分配给'从不'类型. [英] Typescript compiler never Error: Type 'string | number' is not assignable to type 'never'. Type 'string' is not assignable to type 'never'

查看:60
本文介绍了Typescript编译器从不错误:Type' string |号码'不能分配给'从不'类型.输入' 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.

所以我的第一个问题是: string如何?数字类型神奇地变成了永不类型?有什么办法可以解决这个问题?

so my first question is: How come a string | number type magically becomes a never type? Is there any way to fix this?

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

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)

因此,我的第二个问题是:为什么使用 Generics 解决问题,关键字 extends 在这里又是什么黑客呢?

Therefore my second question would be: why using Generics solve the problem and what the hack is the keyword extends here?

顺便说一句,所有代码均以打字稿 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:

常用功能:假设您正在吃蛋糕,但闭着眼睛.您知道这可能是樱桃蛋糕或香蕉蛋糕.您喜欢这种口味,但不能说多么美味的香蕉蛋糕!"因为您不确定这是香蕉蛋糕.

Usual function: Lets imagine you are eating a cake but your eyes are closed. You know that it might be a cherry cake or a banana cake. You like the taste but you cannot say "What a delicious banana cake!" because you are not sure that it's a banana cake.

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

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编译器从不错误:Type&amp;#39; string |号码&amp;#39;不能分配给&amp;#39;从不&amp;#39;类型.输入&amp;#39; string&amp;#39;不能分配给&amp;#39;从不&amp;#39;类型.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆