我有一台DeepWriteable型的和一台PositiveNumber号的.PositiveNumbernumber的延伸,但DeepWriteable<PositiveNumber>不是.品牌字符串类型的情况也是如此.这里发生了什么事?

type DeepWriteable<T> = { -readonly [P in keyof T]: DeepWriteable<T[P]> };
type PositiveNumber = number & { __brand: 'PositiveNumber' };
type NonEmptyString = string & { __brand: 'NonEmptyString' };

type test1 = PositiveNumber extends number ? true : false;
// TRUE
type test2 = DeepWriteable<PositiveNumber> extends number ? true : false;
// FALSE
type test3 = NonEmptyString extends string ? true : false;
// TRUE
type test4 = DeepWriteable<NonEmptyString> extends string ? true : false;
// FALSE

(顺便说一句,我只是问品牌类型,因为普通的numberstring似乎没有这种行为)

type test5 = DeepWriteable<number> extends number ? true : false;
// TRUE
type test6 = DeepWriteable<string> extends string ? true : false;
// TRUE

我求助于只在DeepWriteable上加一个复选标记,以不映射超过numberstring的值,这很好用,但我很好奇为什么这是必要的.

这是因为-readonly转换使其成为非同态映射类型吗?我想我也许能明白为什么string会发生这种情况,因为lengthreadonly.number号有没有类似的readonly号房源?

推荐答案

branded primitive(具有类对象类型的primitive type)上的任何mapped type个(甚至homomorphic个)将最终销毁原始类型.

microsoft/TypeScript#12447中,规则的、非标记的基元上的同态映射类型被特例用来返回基元而不做任何改变.

但是对于标记的原语,您将获得输入类型的所有属性和外观属性的映射,这意味着DeepWriteable<PositiveNumber>将为您提供所有Number个接口属性和__brand个属性的结果.

正如关于相关问题microsoft/TypeScript#35992的第this comment条所述:

使用对象类型标记原语是一项风险自负的工作.基本上,只要类型不经过简化转换,您就可以这样做……也就是说,我描述的是当前的行为,而不是对future 行为的任何promise .太..我们确实在内部使用了一些品牌,但当我们遇到奇怪的????时,不会对自己提出错误

因此,看起来我们的建议是避免对标记的原语进行过多的类型操作,或者至少彻底测试这种操作并调整它们,以处理当类型不像您希望的那样组合时出现的任何意外问题.

Typescript相关问答推荐

Typescript对每个属性具有约束的通用类型

VS代码1.88.0中未出现自动导入建议

在Angular中,如何在文件上传后清除文件上传文本框

有没有可能使用redux工具包的中间件同时监听状态的变化和操作

使用带有RxJS主题的服务在Angular中的组件之间传递数据

在将对象从一个对象转换成另一个对象时,可以缩小对象的键吗?

TypeScript类型不匹配:在返回类型中处理已经声明的Promise Wrapper

类型脚本强制泛型类型安全

输入元素是类型变体的对象数组的正确方法是什么?'

使用Dockerfile运行Vite React应用程序时访问env变量

在列表的指令中使用intersectionObservable隐藏按钮

如何使这种一对一关系在旧表上起作用?

如何在不违反挂钩规则的情况下动态更改显示内容(带有状态)?

为什么在泛型方法中解析此promise 时会出现类型错误?

有没有一种更好的方法来存储内存中的数据,而不是在类型脚本中使用数组和基于索引的函数?

有没有一种方法可以提升对象的泛型级别,而对象的值是泛型函数?

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数

如何在Vuetify 3中导入TypeScript类型?

如何让Record中的每个值都有独立的类型?

如何从列表中仅 Select 一种类型?