首页 > 解决方案 > Typescript 3 和数组类型节点

问题描述

我最近从typescript@2.9.xto更新typescript@3.0.3,现在我的转译器程序出现错误。你可以在Github找到源代码。

转译器使用 typescript APIts.createProgram(...)program.getTypeChecker()来检查当前节点的实际类型。您可以在 中查看转译设置src/compiler/Compiler.ts

我的测试仍然有效,但数组类型测试停止工作。这是Travis CI 链接查看测试输出。

我的猜测是该Types.isArray()函数src/transpiler/Types.ts返回错误的布尔值。在typescript@3此函数接收语法种类元素ts.SyntaxKind.ArrayTypets.SyntaxKind.TupleType. 当我使用数组类型代码调试我的测试时,例如:

const testArray: number[] = [1,2,3,4]
const secondIndex: number = testArray[2];

Types.isArray()接收一个语法类型为ts.SyntaxKind.TypeLiteral.

Typescript 已修改元组类型元素以启用泛型。这是TypeLiteral吗?这种重大更改可能会也可能不会影响我的代码。

如果有任何其他问题,请提出,我将尝试更新此帖子。

谢谢你的帮助!

标签: typescripttypescript3.0

解决方案


我刚刚发现,可以通过变量的符号获取变量的类型。测试变量时,必须在某处声明它。这个声明应该有一个类型,这个类型可以用来检测这是一个数组还是元组类型。

我重构了isArray(...)函数以反映变量声明类型。这是新功能:

public static isArray(node: ts.Node, typeChecker: ts.TypeChecker): boolean {

    // get the node type
    const type = typeChecker.getTypeAtLocation(node);
    const nodeType = typeChecker.typeToTypeNode(type);
    const symbol = typeChecker.getSymbolAtLocation(node);

    let typeLiteralArrayTypes: ts.SyntaxKind[];

    // at typescript >= 3 array types can be type literals
    if (symbol && symbol.declarations && nodeType.kind === ts.SyntaxKind.TypeLiteral) {

        typeLiteralArrayTypes = symbol.declarations.map(dec => {
            return (dec as any).type.kind;
        });
    }

    // make the test
    return nodeType
        // is an array literal
        && ts.isArrayLiteralExpression(node)
        // is a typescript 3 type literal
        || (typeLiteralArrayTypes
            && typeLiteralArrayTypes.every(typeLiteral => typeLiteral === ts.SyntaxKind.ArrayType || typeLiteral === ts.SyntaxKind.TupleType)
        )
        // normal types (typescript < 3)
        || (nodeType.kind === ts.SyntaxKind.ArrayType || nodeType.kind === ts.SyntaxKind.TupleType);
}

我确信这不是一个解决方案,但这种变化满足了我的测试用例。如果您有更好的解决方案,请分享!


推荐阅读