过滤掉联合类型中的一种可能性
Filtering out one possibility in a union type
以下不编译:
function f(n: number): (number|null) {
return n > 0 ? n : null;
}
function g(a: number[]): number[] {
return a.map(f).filter(n => n);
}
问题是,编译器不理解 filter() 的语义,也没有意识到它会忽略列表中所有错误的条目。结果,它失败了 "Type '(number | null)[]' is not assignable to type 'number[]'."
以下确实有效:
function g(n: number[]): number[] {
return n.map(f).filter(n => n).map(n => n!);
}
但经历了一个毫无意义的循环。这也行
function g(a: number[]): number[] {
return a.map(f).filter(n => n) as number[];
}
但是这样的演员表会掩盖许多罪过。还有其他建议吗?
你可以把过滤方法提取出来,用Type Guards让它更精确一些。
像这样:
function f(n: number): (number | null) {
return n > 0 ? n : null
}
function hasValue(n: number | null): n is number {
return !!n
}
function g(a: number[]): number[] {
return a.map(f).filter(hasValue)
}
注意。 !!n 也会过滤掉 0,因此不完全正确但适合突出显示类型保护
以下不编译:
function f(n: number): (number|null) {
return n > 0 ? n : null;
}
function g(a: number[]): number[] {
return a.map(f).filter(n => n);
}
问题是,编译器不理解 filter() 的语义,也没有意识到它会忽略列表中所有错误的条目。结果,它失败了 "Type '(number | null)[]' is not assignable to type 'number[]'."
以下确实有效:
function g(n: number[]): number[] {
return n.map(f).filter(n => n).map(n => n!);
}
但经历了一个毫无意义的循环。这也行
function g(a: number[]): number[] {
return a.map(f).filter(n => n) as number[];
}
但是这样的演员表会掩盖许多罪过。还有其他建议吗?
你可以把过滤方法提取出来,用Type Guards让它更精确一些。
像这样:
function f(n: number): (number | null) {
return n > 0 ? n : null
}
function hasValue(n: number | null): n is number {
return !!n
}
function g(a: number[]): number[] {
return a.map(f).filter(hasValue)
}
注意。 !!n 也会过滤掉 0,因此不完全正确但适合突出显示类型保护