S
S
sanex33392016-05-13 15:43:54
typescript
sanex3339, 2016-05-13 15:43:54

Typescript and types by conditions. How to do it right?

There are several ITreeNode interfaces and IIdentifierNode inherited from it and a few others, etc.
There is a code:

estraverse.replace(catchClauseNode.param, {
            leave: (node: ITreeNode, parentNode: ITreeNode) => {
                switch (node.type) {
                    case 'Identifier':
                        this.catchClauseParam.set(node.name, Utils.getRandomVariableName());
                        node.name = this.catchClauseParam.get(node.name);

                        break;

                    default:
                        return estraverse.VisitorOption.Skip;
                }
            }
        });

In the 1st case, a node will get that will implement the IIdentifierNode interface, but since the arrow function parameter specifies `node: ITreeNode`, the compiler will swear at the property `node.name`.
And here it would be to cast inside `case` ITreeNode in IIdentifierNode, but you have to cast in three places, which sucks.
How beautiful to resolve this situation, except by setting `node: any`?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
sanex3339, 2016-05-13
@sanex3339

Made so far through user defined guard functions:
https://github.com/Microsoft/TypeScript/issues/1007

public static isIdentifierNode (node: ITreeNode): node is IIdentifierNode {
    return node.type === 'Identifier';
}

estraverse.replace(catchClauseNode.param, {
    leave: (node: ITreeNode, parentNode: ITreeNode) => {
        if (NodeUtils.isIdentifierNode(node)) {
            this.catchClauseParam.set(node.name, Utils.getRandomVariableName());
            node.name = this.catchClauseParam.get(node.name);

            return;
        }

        return estraverse.VisitorOption.Skip;
    }
});

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question