【发布时间】:2020-09-18 04:35:39
【问题描述】:
我有一个树状数据结构。我想用节点包装器包装每个树节点,它为节点添加了额外的功能。但同时我想保持打字完整。有人可以帮我解决这个问题吗?
这是一个显示我想要实现的示例
const a = { children: [], value: 12 } as Node<number>;
const b = { children: [], value: 'string' } as Node<string>;
const c = { children: [b, a], value: true } as Node<boolean>;
const root = { children: [c]; value: null } as Node<null>;
// wrap node data with some functions, but keep typings stable
const wrappedNode = wrapNode(root);
wrappedNode.value; // type should be => null
wrappedNode.children[0].value; // type should be => boolean
wrappedNode.children[0].children[0].value; // type should be => string
wrappedNode.children[0].children[1].value; // type should be => number
我目前的方法如下:
interface Node<T, C extends Node<unknown, any[]>[]> {
children: [...C];
value: T;
}
interface WrapNode<T, C extends Node<unknown, any[]>[]> {
children: WrapNode<any, [...C]>[];
value: T;
computeValue(): any;
}
function createNode<T, C extends Node<unknown, any[]>[]>(value: T, children: [...C]): Node<T, [...C]> {
return {
value,
children,
};
}
export function wrapNode<T, C extends Node<any, any>[]>(node: Node<T, C>): WrapNode<T, typeof node.children> {
const value = node.value;
return {
...node,
computeValue: () => value,
children: node.children.map(child => wrapNode(child)),
// ^^^^^ ^^^^^^^^^^^^^^^
// types are: C[number] wrapNode<any, any>(n: Node<any, any>)
};
}
const a = createNode(12, []);
const b = createNode('str', []);
const c = createNode(null, [b, a]);
const x = wrapNode(c);
x.value; // gives me type null, ok!
x.children[0].value; // gives me any :(
x.children[1].value; // gives me any too :(
使用 TypeScript 是否有可能?如果有帮助,我正在使用 TypeScript 4.0.2。在此先感谢:)
【问题讨论】:
标签: typescript typescript-typings