我想用一个对象上的一个键来缩小字体。示例:
class TextNode {
readonly type = 'text_node';
}
class ImageNode {
readonly type = 'image_node';
url: string;
}
type MarkupNode = TextNode | ImageNode;
type Hook<Type extends MarkupNode['type']> = (node: { type: Type }) => { type: Type };
type Hooks = { [NodeType in MarkupNode['type']]?: Hook<NodeType> };
const hooks: Hooks = {
image_node: node => { // I'd like node to be an ImageNode
node.url = 'https://images.com/the-image';
return node;
},
};
这当然会导致错误Property 'url' does not exist on type '{ type: "text_node"; }'
。令人反感的行是type Hook<Type> = (node: { type: Type }) => { type: Type };
,但我不确定是否可以在此处提取正确的MarkupNode
类型。
也许我需要一个辅助函数来包装hooks对象?
答案 0 :(得分:1)
您可以执行所需的操作,但是在映射类型中,您将需要使用Extract
条件类型来提取联合的适当成员:
class TextNode {
readonly type = 'text_node';
}
class ImageNode {
readonly type = 'image_node';
url: string;
}
type MarkupNode = TextNode | ImageNode;
type Hook<TNode> = (node: TNode) => TNode;
type Hooks = { [NodeType in MarkupNode['type']]?: Hook<Extract<MarkupNode, { type: NodeType }>> };
const hooks: Hooks = {
image_node: node => { // is now ImageNode
node.url = 'https://images.com/the-image';
return node;
},
};
Extract
条件类型将提取与第二个type参数中指定的type
相同的type
的并集类型。