Typescript 3 и узлы типа массива - PullRequest
0 голосов
/ 01 сентября 2018

Я недавно обновил с typescript@2.9.x до typescript@3.0.3, и теперь у меня есть ошибки в моей программе транспилятора. Вы можете найти исходный код на Github .

Транспортер использует API машинописи с ts.createProgram(...) и program.getTypeChecker(), чтобы проверить фактический тип текущего узла. Вы можете увидеть настройку прозрачности в src/compiler/Compiler.ts.

Мои тесты все еще работают, но тесты типов массивов перестали работать. Вот ссылка Travis CI для просмотра результатов теста.

Я предполагаю, что функция Types.isArray() в src/transpiler/Types.ts возвращает неправильное логическое значение. До typescript@3 эта функция получала синтаксические элементы вида ts.SyntaxKind.ArrayType и ts.SyntaxKind.TupleType. Когда я отлаживаю свои тесты с помощью кода типа массива, например:

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

Types.isArray() получит узел с синтаксическим видом ts.SyntaxKind.TypeLiteral.

В Typescript был изменен элемент типа кортежа для включения обобщений. Это TypeLiteral? Эти критические изменения могут повлиять или не повлиять на мой код.

Если есть какие-либо дополнительные вопросы, пожалуйста, задавайте, я постараюсь обновить этот пост.

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 01 сентября 2018

Я только что понял, что можно получить тип переменной через ее символ. При тестировании переменной она должна быть где-то объявлена. В этом объявлении должен быть указан тип, и этот тип можно использовать для определения типа массива или кортежа.

Я реорганизовал функцию 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);
}

Я уверен, что это не решение, но это изменение удовлетворило мои контрольные примеры. Если у вас есть лучшее решение, пожалуйста, поделитесь им!

...