我有以下简单的HOF
function myHOF(input: any, typeguard: (thing: any) => boolean) {
if (typeguard(input)) {
return input;
}
}
使用typeguard功能
function myTypeguard(input: any): input is Array<any> {
return Array.isArray(input);
}
用作
const val = [1,2];
const thing = myHOF(val, myTypeguard); // <- should be Array<any> | undefined
显然,这过于简单,但这种类型的东西在创建通用的树遍历HOF时变得很重要。这个语言有兼容性吗?
更有趣的例子
export function* depthFirstRetrieval<T=PlanNode, L=PlanNode>(
jxml: T,
stopConditional: (obj: PlanNode) => boolean,
) {
if (stopConditional(jxml)) {
yield jxml;
} else {
for (const key of Object.keys(jxml) as Array<keyof typeof jxml>) {
const property = jxml[key];
if (Array.isArray(property)) {
for (const childNode of property) {
yield *depthFirstRetrieval(childNode, stopConditional);
}
}
}
}
}
应该产生类型L
答案 0 :(得分:2)
当然,您可以在高阶函数中使用类型保护签名。事实上,TypeScript standard library's type definition for Array.filter()
使用它来允许您返回比您过滤的数组更窄的数组:
interface Array { filter( callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any ): S[];
无论如何,对于你的例子:
function myHOF<T>(input: any, typeguard: (thing: any) => thing is T) : T | undefined {
if (typeguard(input)) {
return input;
}
return;
}
myHOF()
中的T
是通用的,因为您希望使用类型保护输出您测试的相同类型T
。另请注意typeguard
参数如何注释为返回类型谓词thing is T
的函数。
现在您可以按预期使用它:
function myTypeguard(input: any): input is Array<any> {
return Array.isArray(input);
}
const val = [1,2];
const thing = myHOF(val, myTypeguard); // thing is any[] | undefined
编辑:我对PlanNode
的其他案例不是100%肯定,但可能是这样:
export function* depthFirstRetrieval<T extends PlanNode, L extends PlanNode>(
jxml: T,
stopConditional: (obj: PlanNode) => obj is L,
): IterableIterator<L>
{
if (stopConditional(jxml)) {
yield jxml;
} else {
for (const key of Object.keys(jxml) as Array<keyof typeof jxml>) {
const property = jxml[key];
if (Array.isArray(property)) {
for (const childNode of property) {
yield *depthFirstRetrieval(childNode, stopConditional);
}
}
}
}
}
希望有所帮助;祝你好运!