TypeScript:为什么我不能分配类型为 { a: “a", b: “b"; 的对象的有效字段?} [英] TypeScript: Why can't I assign a valid field of an object with type { a: "a", b: "b" }
问题描述
我从一个常量数组
创建了以下类型:
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屋!