You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constx: [number,number,number]=[1,2,3]constx=arr[0]// `x` type is `number`consty=arr[1000]// error: Tuple type '[number, number, number]' of length '3' has no element at index '9'.
当索引溢出时, 直接编译报错
第二种方法是使用 const assertions, 即断言成字面量类型:
constarr=[1,2,3]asconst// `arr` type is `readonly [1, 2, 3]`constx=arr[0]// `x` type is `number`consty=arr[1000]// error: Tuple type '[number, number, number]' of length '3' has no element at index '9'.
noUncheckedIndexedAccess
其实没啥聊的, 这个配置属于 4.1 版本的一个新 feature, 该属性的作用在于使用索引访问某类型属性时, 该类型属性会被加上
undefined
类型:举个例子: 在没有该配置的情况下, 访问一个普通的 array 的类型如下:
实际上这样的类型是不特别准确的, 由于
arr
这个数组长度没有限制, ts 没有足够的信息去判断其元素到底有多少个, 因此即使索引超过初始化定义的长度, ts 还是认为该元素"存在"noUncheckedIndexedAccess
这一配置能够在使用索引访问时, 添加undefined
类型:可以看到开启配置之后, 任何索引的访问都会带上
undefined
类型, 毕竟 ts 此时也不确定 arr 具体的形状是啥样了, 甚至是一个空 array 都是有可能的.Tuple & const assertions
那如何定义固定长度的 array 类型呢? 一种方法是定义为 Tuple 类型:
当索引溢出时, 直接编译报错
第二种方法是使用 const assertions, 即断言成字面量类型:
使用这种类型断言之后, 类型会自动加上
readonly
关键字, ts 编译器就知道这种数据类型是immutable
的, 自然长度也不会变了以上两种方法不管
noUncheckedIndexedAccess
有没有配置, 都能正确识别索引溢出的错误自定义类型
然而有一种情况下识别出的元素类型还是存在
undefined
类型的.这里保持
noUncheckedIndexedAccess
配置开启, 有以下代码:我们仍旧使用
Tuple
类型声明数组, 并且严格规定其元素. 但访问的索引给定一个比较宽泛的类型number
, 这时候去拿数组里的元素时发现他的类型又给出了undefined
类型真实的场景会有, 当使用
map()
,forEach()
这些方法时, 可能会有(其实并没有)如下代码:这时候
v
类型是1 | 2 | 3
, 但是我自己用索引拿到的元素b
类型却是1 | 2 | 3 | undefined
, 有点困惑...我想 ts 编译器应该也困惑吧, 毕竟索引类型是
number
了, 它也不知道具体是哪个索引, 所以我只能又给一个undefined
, 虽然我数组的类型是严格的Tuple
所以这里的索引
i
需要更加准确, 如果手动给的话, 即为0 | 1 | 2
. 但是该如何根据已知的数组a
和它的类型A
自动推断出对应的索引类型呢?比较通用并且容易想到的一种做法是用
keyof
:虽然最后的结果类型是
string
, 但是对于索引已经够用了IndexOf
另一种做法就是自定义一个类型, 这里叫
IndexOf
, 该类型接受一个类型参数, 即数组的类型, 返回值是该数组的索引类型, 这里先看实现:使用就非常简单了
最后得到的类型顺序不重要(我觉得...)
简单讲一下过程:
T
和S
是两个泛型参数,T
的形状是一个 array,S
类型为数字数组, 默认为一个空数组类型. 这个S
存放了每次递归的状态, 这里后面会讲?
前的extends
语句, 这个语句是递归的终止条件, 满足条件为当T
的长度和S
的长度一样?
后的第一条语句, 这条语句为返回结果, 返回的是S[number]
, 也就是对S
取里面所有元素的 union 的值S
自增, 从一开始的[]
, 一直到每次递增添加一个数字, 所以最后的S
值为[0, 1, 2]
最后发现了一个可以做类型体操的地方: type-challenges
参考
The text was updated successfully, but these errors were encountered: