@sanex3339

Typescript и типы по условиям. Как правильно поступить?

Есть несколько интерфейсов ITreeNode и наследуемые от него IIdentifierNode и еще несколько других т.п.

Есть код:

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;
                }
            }
        });


В 1-й case попадет нода, которая будет реализовывать интерфейс IIdentifierNode, но поскольку в параметре arrow function указано `node: ITreeNode` то компилятор будет ругаться на св-во `node.name`.
И вот тут бы скастовать внутри `case` ITreeNode в IIdentifierNode, но кастовать придется в трех местах, что хреново.

Как красиво разрулить данную ситуацию, кроме как выставив `node: any`?
  • Вопрос задан
  • 195 просмотров
Пригласить эксперта
Ответы на вопрос 1
@sanex3339 Автор вопроса
Сделал пока через 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;
    }
});
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы