TypeScript:为什么我不能分配类型为 { a: “a", b: “b"; 的对象的有效字段?} [英] TypeScript: Why can't I assign a valid field of an object with type { a: "a", b: "b" }

查看:38
本文介绍了TypeScript:为什么我不能分配类型为 { a: “a", b: “b"; 的对象的有效字段?}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从一个常量数组 ['a', '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)

ab 的交集产生 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屋!

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