typescript - TypeScript:为什么我不能分配类型为 { a: "a", b: "b" } 的对象的有效字段
问题描述
我从一个常量数组创建了以下类型<const>['a', 'b]
:
const paths = <const>['a', 'b']
type Path = typeof paths[number]
type PathMap = {
[path in Path]: path
}
Path
等于"a" | "b"
PathMap
等于{a: "a", b: "b"}
然后下面的代码编译得很好:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {
map['a'] = 'a'
return map
}, <PathMap>{})
这也有效:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {
return { ...map, [p]: p }
}, <PathMap>{})
但以下代码无法编译:
const BASE_PATHS = paths.reduce((map: PathMap, p: Path) => {
map[p] = p
return map
}, <PathMap>{})
这给了我这个错误map[p] = p
:
TS2322: Type 'string' is not assignable to type 'never'. Type 'string' is not assignable to type 'never'.
为什么会这样?
感谢您的帮助!
解决方案
我相信这是因为对象的键类型是逆变的。
有关更多信息,请参阅此答案。
同样,同一类型变量在逆变位置的多个候选会导致推断出交集类型。
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)
的交集a
并b
产生never
。
如果as const
从中删除paths
将编译,因为string & string = string
顺便说一句,由于您使用的是功能方法,请尽量避免对象突变。
在这里,在我的博客中,您可以找到有关 TS 突变的更多信息
归功于@aleksxor
在这里你可以找到官方解释
推荐阅读
- go - 获取 GORM 中的递归字段值
- pine-script - 点值计算
- html - 在 CSS 中控制单选按钮内圆的大小
- mysql - MySql 有 1.09 亿条记录 - 非常慢,有键
- node.js - 客户端调用调用外部 api 的服务器时出现 CORS 问题
- laravel - nginx fpm-php 基于位置的多个 laravel 实例
- ruby-on-rails - 将 2 个表中的记录组合成 1 个 ActiveRecord 模型
- c# - 如何在重用之前清理 ListViewItem 的状态?
- amazon-web-services - PMU x86-64 performance counters not showing in perf under AWS
- c# - 如何从 Rider 调试 WSL2 中的进程?