diff --git a/packages/compiler-cli/src/metadata/evaluator.ts b/packages/compiler-cli/src/metadata/evaluator.ts index a7afb4e01d..0c312a6f59 100644 --- a/packages/compiler-cli/src/metadata/evaluator.ts +++ b/packages/compiler-cli/src/metadata/evaluator.ts @@ -477,13 +477,10 @@ export class Evaluator { case ts.SyntaxKind.UnionType: const unionType = node; // Remove null and undefined from the list of unions. - // TODO(alan-agius4): remove `n.kind !== ts.SyntaxKind.NullKeyword` when - // TS 3.9 support is dropped. In TS 4.0 NullKeyword is a child of LiteralType. const references = unionType.types .filter( - n => n.kind !== ts.SyntaxKind.NullKeyword && - n.kind !== ts.SyntaxKind.UndefinedKeyword && + n => n.kind !== ts.SyntaxKind.UndefinedKeyword && !(ts.isLiteralTypeNode(n) && n.literal.kind === ts.SyntaxKind.NullKeyword)) .map(n => this.evaluateNode(n)); diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/util.ts b/packages/compiler-cli/src/ngtsc/metadata/src/util.ts index 5d7f6c9841..8575437127 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/util.ts +++ b/packages/compiler-cli/src/ngtsc/metadata/src/util.ts @@ -22,25 +22,22 @@ export function extractReferencesFromType( return []; } - // TODO(alan-agius4): remove `def.elementTypes` and casts when TS 3.9 support is dropped and G3 is - // using TS 4.0. - return (((def as any).elements || (def as any).elementTypes) as ts.NodeArray) - .map(element => { - if (!ts.isTypeQueryNode(element)) { - throw new Error(`Expected TypeQueryNode: ${nodeDebugInfo(element)}`); - } - const type = element.exprName; - const {node, from} = reflectTypeEntityToDeclaration(type, checker); - if (!isNamedClassDeclaration(node)) { - throw new Error(`Expected named ClassDeclaration: ${nodeDebugInfo(node)}`); - } - const specifier = (from !== null && !from.startsWith('.') ? from : ngModuleImportedFrom); - if (specifier !== null) { - return new Reference(node, {specifier, resolutionContext}); - } else { - return new Reference(node); - } - }); + return def.elements.map(element => { + if (!ts.isTypeQueryNode(element)) { + throw new Error(`Expected TypeQueryNode: ${nodeDebugInfo(element)}`); + } + const type = element.exprName; + const {node, from} = reflectTypeEntityToDeclaration(type, checker); + if (!isNamedClassDeclaration(node)) { + throw new Error(`Expected named ClassDeclaration: ${nodeDebugInfo(node)}`); + } + const specifier = (from !== null && !from.startsWith('.') ? from : ngModuleImportedFrom); + if (specifier !== null) { + return new Reference(node, {specifier, resolutionContext}); + } else { + return new Reference(node); + } + }); } export function readStringType(type: ts.TypeNode): string|null { @@ -74,15 +71,12 @@ export function readStringArrayType(type: ts.TypeNode): string[] { return []; } const res: string[] = []; - // TODO(alan-agius4): remove `def.elementTypes` and casts when TS 3.9 support is dropped and G3 is - // using TS 4.0. - (((type as any).elements || (type as any).elementTypes) as ts.NodeArray) - .forEach(el => { - if (!ts.isLiteralTypeNode(el) || !ts.isStringLiteral(el.literal)) { - return; - } - res.push(el.literal.text); - }); + type.elements.forEach(el => { + if (!ts.isLiteralTypeNode(el) || !ts.isStringLiteral(el.literal)) { + return; + } + res.push(el.literal.text); + }); return res; } diff --git a/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts index 72a8f54139..263a31d534 100644 --- a/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts @@ -64,9 +64,7 @@ export class TypeScriptReflectionHost implements ReflectionHost { // optional tokes that don't have providers. if (typeNode && ts.isUnionTypeNode(typeNode)) { let childTypeNodes = typeNode.types.filter( - // TODO(alan-agius4): remove `childTypeNode.kind !== ts.SyntaxKind.NullKeyword` when - // TS 3.9 support is dropped. In TS 4.0 NullKeyword is a child of LiteralType. - childTypeNode => childTypeNode.kind !== ts.SyntaxKind.NullKeyword && + childTypeNode => !(ts.isLiteralTypeNode(childTypeNode) && childTypeNode.literal.kind === ts.SyntaxKind.NullKeyword)); diff --git a/packages/compiler-cli/src/ngtsc/transform/src/declaration.ts b/packages/compiler-cli/src/ngtsc/transform/src/declaration.ts index acc757c6e6..f5f3c26e5a 100644 --- a/packages/compiler-cli/src/ngtsc/transform/src/declaration.ts +++ b/packages/compiler-cli/src/ngtsc/transform/src/declaration.ts @@ -239,33 +239,6 @@ export class ReturnTypeTransform implements DtsTransform { } transformClassElement(element: ts.ClassElement, imports: ImportManager): ts.ClassElement { - // // TODO(alan-agius4): Remove when we no longer support TS 3.9 - // TS <= 3.9 - if (ts.isMethodSignature(element)) { - const original = ts.getOriginalNode(element) as ts.MethodDeclaration; - if (!this.typeReplacements.has(original)) { - return element; - } - const returnType = this.typeReplacements.get(original)!; - const tsReturnType = translateType(returnType, imports); - const methodSignature = ts.updateMethodSignature( - /* node */ element, - /* typeParameters */ element.typeParameters, - /* parameters */ element.parameters, - /* type */ tsReturnType, - /* name */ element.name, - /* questionToken */ element.questionToken); - - // Copy over any modifiers, these cannot be set during the `ts.updateMethodSignature` call. - (methodSignature.modifiers as ts.ModifiersArray | undefined) = element.modifiers; - - // A bug in the TypeScript declaration causes `ts.MethodSignature` not to be assignable to - // `ts.ClassElement`. Since `element` was a `ts.MethodSignature` already, transforming it into - // this type is actually correct. - return methodSignature as unknown as ts.ClassElement; - } - - // TS 4.0 + if (ts.isMethodDeclaration(element)) { const original = ts.getOriginalNode(element, ts.isMethodDeclaration); if (!this.typeReplacements.has(original)) { diff --git a/packages/compiler-cli/src/ngtsc/translator/src/type_translator.ts b/packages/compiler-cli/src/ngtsc/translator/src/type_translator.ts index eb898e05af..180d221f7a 100644 --- a/packages/compiler-cli/src/ngtsc/translator/src/type_translator.ts +++ b/packages/compiler-cli/src/ngtsc/translator/src/type_translator.ts @@ -104,11 +104,7 @@ export class TypeTranslatorVisitor implements o.ExpressionVisitor, o.TypeVisitor visitLiteralExpr(ast: o.LiteralExpr, context: Context): ts.TypeNode { if (ast.value === null) { - // TODO(alan-agius4): Remove when we no longer support TS 3.9 - // Use: return ts.createLiteralTypeNode(ts.createNull()) directly. - return ts.versionMajorMinor.charAt(0) === '4' ? - ts.createLiteralTypeNode(ts.createNull() as any) : - ts.createKeywordTypeNode(ts.SyntaxKind.NullKeyword as any); + return ts.createLiteralTypeNode(ts.createNull()); } else if (ast.value === undefined) { return ts.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword); } else if (typeof ast.value === 'boolean') { diff --git a/packages/compiler-cli/src/transformers/downlevel_decorators_transform.ts b/packages/compiler-cli/src/transformers/downlevel_decorators_transform.ts index 5c4cc4627c..1e27e784fa 100644 --- a/packages/compiler-cli/src/transformers/downlevel_decorators_transform.ts +++ b/packages/compiler-cli/src/transformers/downlevel_decorators_transform.ts @@ -141,14 +141,9 @@ function createCtorParametersClassPropertyType(): ts.TypeNode { ])), undefined)); - // TODO(alan-agius4): Remove when we no longer support TS 3.9 - const nullLiteral = ts.createNull() as any; - const nullType = ts.versionMajorMinor.charAt(0) === '4' ? - ts.createLiteralTypeNode(nullLiteral as any) : - nullLiteral; return ts.createFunctionTypeNode(undefined, [], ts.createArrayTypeNode(ts.createUnionTypeNode([ ts.createTypeLiteralNode(typeElements), - nullType, + ts.createLiteralTypeNode(ts.createNull()), ]))); } @@ -293,13 +288,10 @@ function typeReferenceToExpression( // Ignore any generic types, just return the base type. return entityNameToExpression(typeRef.typeName); case ts.SyntaxKind.UnionType: - // TODO(alan-agius4): remove `t.kind !== ts.SyntaxKind.NullKeyword` when - // TS 3.9 support is dropped. In TS 4.0 NullKeyword is a child of LiteralType. const childTypeNodes = (node as ts.UnionTypeNode) .types.filter( - t => t.kind !== ts.SyntaxKind.NullKeyword && - !(ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword)); + t => !(ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword)); return childTypeNodes.length === 1 ? typeReferenceToExpression(entityNameToExpression, childTypeNodes[0]) : undefined;