TypeScript,——strictNullChecks模式。
假设我有一个可空字符串数组(string | null)[]。什么是单表达式的方式,以这样的方式删除所有的空值,结果有类型字符串[]?
const array: (string | null)[] = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = ???;
数组中。过滤器在这里不起作用:
// Type '(string | null)[]' is not assignable to type 'string[]'
array.filter(x => x != null);
数组推导式可以工作,但TypeScript不支持。
实际上,这个问题可以推广为通过从联合中删除具有特定类型的项来过滤任何联合类型的数组的问题。但是让我们关注带有null和可能未定义的联合,因为这些是最常见的用例。
我已经多次回到这个问题上,希望一些新的Typescript特性或类型可以解决这个问题。
这里有一个简单的技巧,我很喜欢结合map和后续过滤器。
const animals = ['cat', 'dog', 'mouse', 'sheep'];
const notDogAnimals = animals.map(a =>
{
if (a == 'dog')
{
return null!; // just skip dog
}
else {
return { animal: a };
}
}).filter(a => a);
你会看到我返回null!它实际上变成了类型never——这意味着最终的类型没有null。
这与最初的问题略有不同,但我发现自己经常遇到这种情况,这有助于避免另一个方法调用。希望有一天Typescript会提出一个更好的方法。
如果您可以接受另一个.map()的开销,一个优雅的解决方案是使用非空断言操作符。
const array = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = array.filter(s => s != null).map(s => s!);
如果你想保留未定义,你可以在变量上使用typeof,并使用实用程序类型Exclude来从类型中删除空值。
const array = ["foo", "bar", null, "zoo", null];
const filterdArray: string[] = array
.filter(s => s !== null)
.map(s => s as Exclude<typeof s, null>);
或者您可以尝试包:@p4ck93/ts-is
https://www.npmjs.com/package/@p4ck493/ts-is
示例使用CDN方法,但是包也支持typescript。
<script>var exports = {};</script>
<script src="//unpkg.com/@p4ck493/ts-is@3.0.1/dist/index.js"></script>
<script>
const {is} = exports;
console.log('is.string: ', is.string('')); // true
console.log('is.string.empty: ', is.string.empty('')); // true
console.log('is.string.not.empty: ', is.string.not.empty('')); // false
const array = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(is.string.not.empty);
console.log('array:', array);
console.log('filterdArray:', filterdArray);
</script>
UPD
或打字稿:
Import {is} from '@p4ck493/ts-is';
Const array = ["foo", "bar", null, "zoo", null];
const filterdArray = array.filter(is.string.not.empty);
/**
选择:
array.filter (is.not.null);
array.filter (is.not.empty);
array.filter (is.string);
* * /
我已经多次回到这个问题上,希望一些新的Typescript特性或类型可以解决这个问题。
这里有一个简单的技巧,我很喜欢结合map和后续过滤器。
const animals = ['cat', 'dog', 'mouse', 'sheep'];
const notDogAnimals = animals.map(a =>
{
if (a == 'dog')
{
return null!; // just skip dog
}
else {
return { animal: a };
}
}).filter(a => a);
你会看到我返回null!它实际上变成了类型never——这意味着最终的类型没有null。
这与最初的问题略有不同,但我发现自己经常遇到这种情况,这有助于避免另一个方法调用。希望有一天Typescript会提出一个更好的方法。