我构建了一个名为compact
的函数,该函数的作用是删除数组中的所有虚假值。
这是javascript
的{{1}}实现:
compact
这是function compact(arr) {
return arr.filter(Boolean);
}
const MyData = [0, 1, null, 2, undefined, ''];
console.log(compact(MyData))
// => [1, 2]
的{{1}} 键入部分:
Typescript
现在,这是古怪的部分,当我使用compact
代码将其连接时,它实际上无法正常工作:
type Falsy = false | null | 0 | '' | undefined;
type Compact<T extends any[]> = Exclude<T[number], Falsy>;
// some correct test
type MyData = [0, 1, null, 2, undefined, ''];
type MyDataWithoutFalsy = Compact<MyData>
// => type MyDataWithoutFalsy = 1 | 2
它只能是compact
,因为应该排除空字符串。
答案 0 :(得分:4)
问题不是Exclude
的问题,问题在于""
(不仅是此字符串文字,对于任何字符串文字),打字稿通常不会保留字符串文字类型,但它将除非我们给出保留字面量类型的理由,否则应将其扩展为string
。
要向编译器提示您想要文字类型,必须将文字分配给受限于文字基本类型的通用类型参数:
function compact<V extends (string | undefined | boolean | object | number | null), T extends V[]>(arr: T & V[]): Compact<T> {
return arr.filter(Boolean) as Compact<T>;
}
let MyDataWithoutFalsy = compact([0, 1, null, 2, undefined, '']); // number
type Falsy = false | null | 0 | '' | undefined;
type Compact<T extends any[]> = Exclude<T[number], Falsy>;
请注意,这确实意味着compact
才真正可用,除非您以保留文字类型(例如''
)的方式构造数组。
function compact<V extends (string | undefined | boolean | object | number | null), T extends V[]>(arr: T & V[]): Compact<T> {
return arr.filter(Boolean) as Compact<T>;
}
function literalArray<V extends (string | undefined | boolean | object | number | null)>(arr: V[]): V[] {
return arr.filter(Boolean);
}
let arr = literalArray([0, 1, null, 2, undefined, ''])
let MyDataWithoutFalsy = compact(arr); // 1| 2 ... beacuse resons