问题描述
限时送ChatGPT账号..我从一个常量数组
创建了以下类型:
const paths = <const>['a', 'b']路径类型 = 路径类型[编号]类型路径映射 = {[路径中的路径]:路径}
Path
等于 a";|b"
PathMap
等于 {a: "a", b: "b"}
然后下面的代码编译正常:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {地图['a'] = 'a'返回地图}, <PathMap>{})
这也有效:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {返回{ ...地图,[p]:p}}, <PathMap>{})
但以下代码无法编译:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {地图[p] = p返回地图}, <PathMap>{})
在 map[p] = p
处给了我这个错误:
TS2322:类型字符串"不可分配给类型从不".类型 'string' 不能分配给类型 'never'.
为什么会这样?
感谢您的帮助!
解决方案我相信这是因为对象的键类型是逆变的.
有关详细信息,请参阅此答案.><块引用>
同样,逆变位置中同一类型变量的多个候选会导致推断交叉类型.
const paths = ['a', 'b'] as const路径类型 = 路径类型[编号]类型路径映射 = {[路径中的路径]:路径}输入 a = 'a'输入 b = 'b'类型 c = a &b//从不{const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {让 x = 地图 [p]map[p] = p//这里一样返回地图}, {} 作为 PathMap)
a
和 b
的交集产生 never
.
如果你从 paths
中删除 as const
它会编译,因为 string &字符串 = 字符串
顺便说一句,由于您使用的是函数式方法,因此请尽量避免对象突变.
这里,在我的博客中,你可以找到更多关于 TS 突变的信息
感谢 @aleksxor
这里可以找到官方解释
I created the following types from a constant array <const>['a', 'b]
:
const paths = <const>['a', 'b']
type Path = typeof paths[number]
type PathMap = {
[path in Path]: path
}
Path
equals to "a" | "b"
PathMap
equals to {a: "a", b: "b"}
Then the following code compiles fine:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {
map['a'] = 'a'
return map
}, <PathMap>{})
This also works:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {
return { ...map, [p]: p }
}, <PathMap>{})
But the following code does not compile:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {
map[p] = p
return map
}, <PathMap>{})
Which gave me this error at map[p] = p
:
TS2322: Type 'string' is not assignable to type 'never'. Type 'string' is not assignable to type 'never'.
Why is this the case?
Thanks for helping!
解决方案I believe this is because objects are contravariant in their key types.
For more information see this answer.
Likewise, multiple candidates for the same type variable in contra-variant positions causes an intersection type to be inferred.
const paths = ['a', 'b'] as const
type Path = typeof paths[number]
type PathMap = {
[path in Path]: path
}
type a = 'a'
type b = 'b'
type c = a & b // never
{
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {
let x = map[p]
map[p] = p // same here
return map
}, {} as PathMap)
Intersection of a
and b
produces never
.
If you remove as const
from paths
it will compile, because string & string = string
Btw, since you are using functional approach try to avoid object mutations.
Here, in my blog, you can find more information about mutations in TS
Credits to @aleksxor
Here you can find official explanation
这篇关于TypeScript:为什么我不能分配类型为 { a: “a", b: “b"; 的对象的有效字段?}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论