TypeScript, - strictNullChecks模式.
假设我有一个可以为空的字符串数组(字符串| null)[].以表达式为string []的方式删除所有空值的单表达式方法是什么?
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = ???;
Run Code Online (Sandbox Code Playgroud)
Array.filter在这里不起作用:
// Type '(string | null)[]' is not assignable to type 'string[]'
array.filter(x => x != null);
Run Code Online (Sandbox Code Playgroud)
数组理解可能有效,但TypeScript不支持它们.
实际上,通过从联合中删除具有一个特定类型的条目,可以将该问题推广到过滤任何联合类型的数组的问题.但是让我们关注具有null和未定义的联合,因为这些是最常见的用例.
Bij*_*lle 75
您可以在中使用类型谓词函数,.filter以避免选择退出严格类型检查:
function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
return value !== null && value !== undefined;
}
const array: (string | null)[] = ['foo', 'bar', null, 'zoo', null];
const filteredArray: string[] = array.filter(notEmpty);
Run Code Online (Sandbox Code Playgroud)
或者你可以使用array.reduce<string[]>(...).
Mik*_*sky 64
还有一对,因为人们往往忽视了很好的措施flatMap,它可以处理filter和map一气呵成(这也并不需要任何铸造string[]):
// (string | null)[]
const arr = ["a", null, "b", "c"];
// string[]
const stringsOnly = arr.flatMap(f => f ? [f] : []);
Run Code Online (Sandbox Code Playgroud)
std*_*453 44
刚刚意识到你可以这样做:
const nonNull = array.filter((e): e is Exclude<typeof e, null> => e !== null)
Run Code Online (Sandbox Code Playgroud)
这样你:
DLi*_*ght 42
一班轮:
const filteredArray: string[] = array.filter((s): s is string => Boolean(s));
Run Code Online (Sandbox Code Playgroud)
技巧是传递一个类型谓词(:s is string语法)。
这个答案表明Array.filter需要用户提供类型谓词。
注意:如果您不想删除虚假值(例如空字符串),请替换Boolean(s)为。s !== null""
alu*_*ach 40
与@ bijou-trouvaille的答案类似,您只需将声明声明<arg> is <Type>为过滤函数的输出:
array.filter((x): x is MyType => x !== null);
Run Code Online (Sandbox Code Playgroud)
Mat*_*nkt 14
这是一个使用的解决方案NonNullable。我发现它比 @bijou-trouvaille 接受的答案更简洁
function notEmpty<TValue>(value: TValue): value is NonNullable<TValue> {
return value !== null && value !== undefined;
}
Run Code Online (Sandbox Code Playgroud)
const array: (string | null | undefined)[] = ['foo', 'bar', null, 'zoo', undefined];
const filteredArray: string[] = array.filter(notEmpty);
console.log(filteredArray)
[LOG]: ["foo", "bar", "zoo"]
Run Code Online (Sandbox Code Playgroud)
Nit*_*mer 11
您可以将filter结果转换为所需的类型:
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(x => x != null) as string[];
Run Code Online (Sandbox Code Playgroud)
这适用于您提到的更一般的用例,例如:
const array2: (string | number)[] = ["str1", 1, "str2", 2];
const onlyStrings = array2.filter(x => typeof x === "string") as string[];
const onlyNumbers = array2.filter(x => typeof x === "number") as number[];
Run Code Online (Sandbox Code Playgroud)
(游乐场代码)
Rob*_*oli 11
为了避免每个人都不得不一遍又一遍地编写相同的类型保护辅助函数,我将名为 , 的函数捆绑isPresent到isDefined一个isFilled辅助库中:https ://www.npmjs.com/package/ts-is-present
目前的类型定义是:
export declare function isPresent<T>(t: T | undefined | null): t is T;
export declare function isDefined<T>(t: T | undefined): t is T;
export declare function isFilled<T>(t: T | null): t is T;
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
export declare function isPresent<T>(t: T | undefined | null): t is T;
export declare function isDefined<T>(t: T | undefined): t is T;
export declare function isFilled<T>(t: T | null): t is T;
Run Code Online (Sandbox Code Playgroud)
当 Typescript 捆绑此功能时,我将删除该包。但是,现在,享受吧。
如果您已经使用 Lodash,则可以使用compact. 或者,如果您更喜欢 Ramda,那么 ramda 辅助词也有compact功能。
两者都有类型,因此您的 tsc 会很高兴并获得正确的类型。
来自 Lodash d.ts 文件:
/**
* Creates an array with all falsey values removed. The values false, null, 0, "", undefined, and NaN are
* falsey.
*
* @param array The array to compact.
* @return Returns the new array of filtered values.
*/
compact<T>(array: List<T | null | undefined | false | "" | 0> | null | undefined): T[];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18033 次 |
| 最近记录: |