TypeScript
as []
as [] 是不同于 as const 语义的,as const 会额外携带 readonly 语义,不是必要的场景,可以不携带该语义,as [] 表示是一个 空 tuple,用于空数组的 参数默认值,更合适
const DEFAULT_EXTRA = [] as [];
as const
as const 可用于直接生成元组类型,但滥用会导致 readonly 链,如果不是readonly的场景,建议直接定义元组类型(尤其通常都是可变的)。
泛型参数 xxx extends any[]
问题:某个参数的类型具有外部泛型参数限制 any[] 时,不可被赋予 [] 类型。
当某个参数是 any[] 或 [] 或 undefined
(该场景就是 参数可能为 undefined 或一个数组,默认值被设为一个空数组)时,不要使用泛型的形式去限制,也就是不要通过外部传递泛型参数来设定类型。xxx extends any[]
在泛型入参时,会识别 [] 的语义,不可分配给 any[]
Type ‘[]’ is not assignable to type ‘xxx’.
‘[]’ is assignable to the constraint of type ‘xxx’, but ‘xxx’ could be instantiated with a different subtype of constraint ‘any[]’.
即使,这个分配是对的,ts 也要求我们别这么做
从这点也可以看出 [] 的 空tuple 语义,延伸开来可以表示,一个item都没有的array,而 [] extends any[],虽然成立,也就是 any[] 可以被用 [] 分配。
但是在作为泛型参数限制来使用时,这个限制被加强为,不是个 肯定是[] 的 any[]。
所以,一旦明确需要对一个参数限制为 any[] | [],不可使用泛型参数 any[] 限制(any[] | [] 目前不支持,可能以后会支持?并支持类型收缩)。或使用泛型参数限制的同时,将 defaultValue ([]) as 为泛型参数。
这里只所以使用 as 是因为 ts 暂不支持 [] 的准确类型收缩。
另外 使用泛型参数,就表示,这个类型它之后的变量,它一定是来自调用处,提前设置默认值,或函数体内部直接赋值就是不安全的。
// 神奇的例子
function fn3<T extends "a">(): T {
return "a" // error
}
const result = fn3<'a' & { tag: 2 }>().tag // 2
外部传递泛型参数,也只可使用外部的变量,默认值类似内部指定,只能通过 as 来进行。因为 泛型参数,本就是指,可以支持的一整个集合,而指定默认值相当于收缩了这个集合,这样做是不对的(原理未知)。
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#variadic-tuple-types
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#labeled-tuple-elements
可以理解为:
- 泛型constraint 一旦被指定,T extends xx 中的 T 永远不可使用函数体内部的变量
更多泛型参数 infer:https://catchts.com/infer-arguments#generic_constraints
- 由条件1可知,可选参数,且为数组的情况下,类型会生成为 T extends any[] | undefined 如需使用 […T] destructring , 只能直接 …(T! | [])
Info
cnpm cdn
http://npm.taobao.org => http://npmmirror.com
http://registry.npm.taobao.org => http://registry.npmmirror.com
详细说明:https://zhuanlan.zhihu.com/p/465424728
registry: https://registry.npmmirror.com
binary查看地址:https://registry.npmmirror.com/binary.html
binary文件地址:https://registry.npmmirror.com/-/binary/xxx