**类型脚本版本:**3.5.1
搜索词:
属性链接,通用,对象类型参数,条件类型
代码
修改版本的@fatcerberus '试图打破TS。
type Droste<T extends {x:number|string}> = {
value: T,
/**
* Should alternate between string and number
* /
droste: Droste<{x:(T["x"] extends number ? string : number)}>
};
declare const droste: Droste<{x:number}>;
//number
const _0 = droste.droste.droste.droste.droste.droste.droste.droste.droste.droste.droste
.droste.droste.droste.droste.droste.droste.droste.droste.droste.droste
.droste.droste;
const _1 = _0.droste; //string
const _2 = _1.droste; //number
const _3 = _2.droste; //string
const _4 = _3.droste; //Expected number, actual string, ???
const _5 = _4.droste; //string
const _6 = _5.droste; //string
const _7 = _6.droste; //string
const _8 = _7.droste; //string
const _9 = _8.droste; //string
//string forever and ever. Where is `number`?
预期行为:
每次访问.droste
时,应在string
和number
之间交替进行。
或给予最大示例化深度/计数错误。
实际行为:
它在string
和number
之间交替,然后在一段时间后中断。
从这一点上说,它只是坚持与string
。
未给出错误。
Playground链接:
Playground
相关问题:
它类似于#32707
但是,它放弃并将型别解析为string
,而不是any
。
7条答案
按热度按时间atmip9wb1#
我知道,我知道,递归式别名,不好。
接口也会中断,
Playground
不过,它的断裂方式不同。
rsl1atfo2#
看起来它与示例化限制冲突
insrf1ej3#
32707(注解)中概述的解决方法似乎有效,
Playground
我知道这很管用但我不知道为什么会管用
snvhrwxg4#
如果我不得不猜测(这确实是一个猜测),在类型id上有一个示例化的缓存。在原始示例中,您为每个没有缓存值的递归示例化创建了一个新的对象文字类型(具有新的id)。
在修改后的示例中,每个递归都经过
NextDrosteFix
,该NextDrosteFix
是用基元类型示例化的(并且基元类型是内部的)。NextDrosteFix
将被缓存以用于string
和number
处的示例化。7lrncoxx5#
数组类型是否也被认为是用于实习目的的基元类型?
数组类型似乎永远不会给予问题。只有对象文字类型。
[编辑]
对象常值型别、界面和类别(当做为型别参数条件约束使用时)
cx6n0qe36#
我认为数组和元组是缓存的,但我会等待确认。
vd8tlhqk7#