我似乎不知道如何解决它。它抛出以下错误:Type 'string | number' is not assignable to type 'never'
。
这是我的代码。非常感谢任何想法或任何提示。
interface User {
name: string
age: number
}
const user: User = {
name: "someone",
age: 20
}
const getValue = (key: keyof User) => {
return user[key]
}
const setValue = (key: keyof User, value: string | number) => {
let _user: User = Object.assign({}, user);
return _user[key] = value; <---- error is thrown here
}
Run Code Online (Sandbox Code Playgroud)
小智 13
您在函数中声明类型的方式会setValue
导致 Typescript 正确确定 type 不存在可能的值_user[key]
。
让我们更详细地探讨这一点。
您的User
接口包含两个属性,一个是 type string
,另一个是 type number
。
key
您的函数的参数的setValue
类型为keyof User
。
到目前为止一切都很好...
然而,在“编译时”,Typescript 无法确定正在提供哪个键进行查找,因此无法确定哪种特定类型_user[key]
。
Typescript在编译时所知道的,是类型string
或number
. 因此它推断出交集类型string & number
。
哪一组类型既是字符串又是数字?
正确 - 没有这样的类型;因此,Typescript 正确推断 的类型_user[key]
是类型的空集 - 称为类型never
。
首先,使用 Typescript 提示打开您最喜欢的 IDE,并定义一个具有交集类型的变量:
let a : string & number;
Run Code Online (Sandbox Code Playgroud)
描述性地说,这就是说 的类型是和a
的所有可能类型的集合。string
number
Typescript 正确地推断出实际上不存在这样的类型,a
因此类型为never
。
相反,假设您的User
接口具有 type 的两个属性string
。
interface User {
name: string
age: string
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果您传入并仅使用字符串,您的代码将正常工作。
这相当于说 的类型_user[key]
是交集类型string & string
——当然很简单string
;
为了在setValue
函数中进行正确的类型推断,您需要提供一个泛型类型,您可以将其用于函数的key
和value
参数setValue
:
const setValue = <K extends keyof User>(key: K, value: User[K]) => {
const _user: User = Object.assign({}, user); // Consider also the ES6 spread operator here
_user[key] = value;
return _user;
};
Run Code Online (Sandbox Code Playgroud)
或者,如果您想要一个完全通用的setValue
函数,独立于特定类型或对象,您的函数签名可能如下
const setValueOnObj = <T, K extends keyof T>(obj: T, key: K, value: T[K]) => [...]
Run Code Online (Sandbox Code Playgroud)
const setValue = <K extends keyof User>(key: K, value: User[K]) => {\n let _user: User = Object.assign({}, user);\n return _user[key] = value;\n}\n
Run Code Online (Sandbox Code Playgroud)\n然后你就可以得到完美的类型检查
\nsetValue(\'name\', 18); // \xe2\x9d\x8c\nsetValue(\'name\', \'yes\'); // \xe2\x9c\x85\nsetValue(\'age\', \'18\'); // \xe2\x9d\x8c\nsetValue(\'age\', 18); // \xe2\x9c\x85\nsetValue(\'otherKey\', \'something\'); // \xe2\x9d\x8c\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
7561 次 |
最近记录: |