diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 565420738d8ce..f2315bf21fc8a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9851,7 +9851,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamedImports([factory.createImportSpecifier( /*isTypeOnly*/ false, @@ -9944,7 +9944,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { addResult( factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(isTypeOnly, factory.createIdentifier(localName), /*namedBindings*/ undefined), + factory.createImportClause( + /* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined, + factory.createIdentifier(localName), + /*namedBindings*/ undefined, + ), specifier, attributes, ), @@ -9959,7 +9963,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { addResult( factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(isTypeOnly, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName))), + factory.createImportClause( + /* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined, + /*name*/ undefined, + factory.createNamespaceImport(factory.createIdentifier(localName)), + ), specifier, (node as ImportClause).parent.attributes, ), @@ -9986,7 +9994,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - isTypeOnly, + /* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined, /*name*/ undefined, factory.createNamedImports([ factory.createImportSpecifier( @@ -52860,6 +52868,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) { return checkGrammarNamedImportsOrExports(node.namedBindings); } + if (node.phaseModifier === SyntaxKind.DeferKeyword && moduleKind !== ModuleKind.ESNext) { + return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext); + } return false; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0b2951d8dee2d..36f7959b5b0ad 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8433,5 +8433,17 @@ "String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'.": { "category": "Error", "code": 18057 + }, + "Default imports aren't allowed for deferred imports.": { + "category": "Error", + "code": 18058 + }, + "Named imports aren't allowed for deferred imports.": { + "category": "Error", + "code": 18059 + }, + "Deferred imports are only supported when the '--module' flag is set to 'esnext'.": { + "category": "Error", + "code": 18060 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 01a96579861f4..56a758d367aa6 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3685,7 +3685,11 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri } function emitImportClause(node: ImportClause) { - if (node.isTypeOnly) { + if (node.phaseModifier !== undefined) { + emitTokenWithComment(node.phaseModifier, node.pos, writeKeyword, node); + writeSpace(); + } + else if (node.isTypeOnly) { emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); writeSpace(); } diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 694262eeeb54a..77d1a5a8e458d 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -135,6 +135,7 @@ import { ImportClause, ImportDeclaration, ImportEqualsDeclaration, + ImportPhaseModifier, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -4723,14 +4724,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { + function createImportClause(phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { const node = createBaseDeclaration(SyntaxKind.ImportClause); - node.isTypeOnly = isTypeOnly; + if (typeof phaseModifier === "boolean") { + phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined; + } + node.isTypeOnly = phaseModifier === SyntaxKind.TypeKeyword; + node.phaseModifier = phaseModifier; node.name = name; node.namedBindings = namedBindings; node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.namedBindings); - if (isTypeOnly) { + if (phaseModifier === SyntaxKind.TypeKeyword) { node.transformFlags |= TransformFlags.ContainsTypeScript; } node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context @@ -4738,11 +4743,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { - return node.isTypeOnly !== isTypeOnly + function updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { + if (typeof phaseModifier === "boolean") { + phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined; + } + return node.phaseModifier !== phaseModifier || node.name !== name || node.namedBindings !== namedBindings - ? update(createImportClause(isTypeOnly, name, namedBindings), node) + ? update(createImportClause(phaseModifier, name, namedBindings), node) : node; } diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 80df86fd3ceae..f3ed23b582492 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -730,7 +730,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration( /*modifiers*/ undefined, - nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings), + nodeFactory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, namedBindings), nodeFactory.createStringLiteral(externalHelpersModuleNameText), /*attributes*/ undefined, ); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 59ad1f030220f..44fa145fbc293 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -123,6 +123,7 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, + ImportPhaseModifier, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -7190,6 +7191,7 @@ namespace Parser { // could be legal, it would add complexity for very little gain. case SyntaxKind.InterfaceKeyword: case SyntaxKind.TypeKeyword: + case SyntaxKind.DeferKeyword: return nextTokenIsIdentifierOnSameLine(); case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: @@ -7221,7 +7223,7 @@ namespace Parser { case SyntaxKind.ImportKeyword: nextToken(); - return token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || + return token() === SyntaxKind.DeferKeyword || token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token()); case SyntaxKind.ExportKeyword: let currentToken = nextToken(); @@ -7295,6 +7297,7 @@ namespace Parser { case SyntaxKind.NamespaceKeyword: case SyntaxKind.TypeKeyword: case SyntaxKind.GlobalKeyword: + case SyntaxKind.DeferKeyword: // When these don't start a declaration, they're an identifier in an expression statement return true; @@ -8365,21 +8368,29 @@ namespace Parser { identifier = parseIdentifier(); } - let isTypeOnly = false; + let phaseModifier: ImportPhaseModifier | undefined; if ( identifier?.escapedText === "type" && (token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) && (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration()) ) { - isTypeOnly = true; + phaseModifier = SyntaxKind.TypeKeyword; identifier = isIdentifier() ? parseIdentifier() : undefined; } + else if (identifier?.escapedText === "defer" && token() !== SyntaxKind.FromKeyword) { + phaseModifier = SyntaxKind.DeferKeyword; + identifier = undefined; + if (isIdentifier()) { + parseErrorAtCurrentToken(Diagnostics.Default_imports_aren_t_allowed_for_deferred_imports); + identifier = parseIdentifier(); + } + } - if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration()) { - return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, isTypeOnly); + if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phaseModifier !== SyntaxKind.DeferKeyword) { + return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, phaseModifier === SyntaxKind.TypeKeyword); } - const importClause = tryParseImportClause(identifier, afterImportPos, isTypeOnly); + const importClause = tryParseImportClause(identifier, afterImportPos, phaseModifier, /*skipJsDocLeadingAsterisks*/ undefined); const moduleSpecifier = parseModuleSpecifier(); const attributes = tryParseImportAttributes(); @@ -8388,7 +8399,7 @@ namespace Parser { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function tryParseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks = false) { + function tryParseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks = false) { // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; @@ -8398,7 +8409,7 @@ namespace Parser { token() === SyntaxKind.AsteriskToken || // import * token() === SyntaxKind.OpenBraceToken // import { ) { - importClause = parseImportClause(identifier, pos, isTypeOnly, skipJsDocLeadingAsterisks); + importClause = parseImportClause(identifier, pos, phaseModifier, skipJsDocLeadingAsterisks); parseExpected(SyntaxKind.FromKeyword); } return importClause; @@ -8464,7 +8475,7 @@ namespace Parser { return finished; } - function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks: boolean) { + function parseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks: boolean) { // ImportClause: // ImportedDefaultBinding // NameSpaceImport @@ -8480,11 +8491,19 @@ namespace Parser { parseOptional(SyntaxKind.CommaToken) ) { if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(true); - namedBindings = token() === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports); + if (token() === SyntaxKind.AsteriskToken) { + namedBindings = parseNamespaceImport(); + } + else { + if (phaseModifier === SyntaxKind.DeferKeyword) { + parseErrorAtCurrentToken(Diagnostics.Named_imports_aren_t_allowed_for_deferred_imports); + } + namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports); + } if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false); } - return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings), pos); + return finishNode(factory.createImportClause(phaseModifier, identifier, namedBindings), pos); } function parseModuleReference() { @@ -9518,7 +9537,7 @@ namespace Parser { identifier = parseIdentifier(); } - const importClause = tryParseImportClause(identifier, afterImportTagPos, /*isTypeOnly*/ true, /*skipJsDocLeadingAsterisks*/ true); + const importClause = tryParseImportClause(identifier, afterImportTagPos, SyntaxKind.TypeKeyword, /*skipJsDocLeadingAsterisks*/ true); const moduleSpecifier = parseModuleSpecifier(); const attributes = tryParseImportAttributes(); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 50e827c17bd24..db53e197fecef 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -203,6 +203,7 @@ export const textToKeywordObj: MapLike = { true: SyntaxKind.TrueKeyword, try: SyntaxKind.TryKeyword, type: SyntaxKind.TypeKeyword, + defer: SyntaxKind.DeferKeyword, typeof: SyntaxKind.TypeOfKeyword, undefined: SyntaxKind.UndefinedKeyword, unique: SyntaxKind.UniqueKeyword, diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 7c41bcccc3e7a..7608d5333e1e5 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -886,7 +886,7 @@ export function transformDeclarations(context: TransformationContext): Transform decl.modifiers, factory.updateImportClause( decl.importClause, - decl.importClause.isTypeOnly, + decl.importClause.phaseModifier, visibleDefaultBinding, /*namedBindings*/ undefined, ), @@ -902,7 +902,7 @@ export function transformDeclarations(context: TransformationContext): Transform decl.modifiers, factory.updateImportClause( decl.importClause, - decl.importClause.isTypeOnly, + decl.importClause.phaseModifier, visibleDefaultBinding, namedBindings, ), @@ -918,7 +918,7 @@ export function transformDeclarations(context: TransformationContext): Transform decl.modifiers, factory.updateImportClause( decl.importClause, - decl.importClause.isTypeOnly, + decl.importClause.phaseModifier, visibleDefaultBinding, bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, ), diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index bcb0cbf8ee2cc..885f4c5d67ad6 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -172,7 +172,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B for (const [importSource, importSpecifiersMap] of arrayFrom(currentFileState.utilizedImplicitRuntimeImports.entries())) { if (isExternalModule(node)) { // Add `import` statement - const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values()))), factory.createStringLiteral(importSource), /*attributes*/ undefined); + const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values()))), factory.createStringLiteral(importSource), /*attributes*/ undefined); setParentRecursive(importStatement, /*incremental*/ false); statements = insertStatementAfterCustomPrologue(statements.slice(), importStatement); } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index 2f2d23c468089..5bd5253933de6 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -219,7 +219,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S const importStatement = factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamedImports([ factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("createRequire"), createRequireName), @@ -351,7 +351,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S const importDecl = factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamespaceImport( synthName, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 75656cf5aefab..cc3da23d2067b 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2282,11 +2282,11 @@ export function transformTypeScript(context: TransformationContext): Transformer * @param node The import clause node. */ function visitImportClause(node: ImportClause): VisitResult | undefined { - Debug.assert(!node.isTypeOnly); + Debug.assert(node.phaseModifier !== SyntaxKind.TypeKeyword); // Elide the import clause if we elide both its name and its named bindings. const name = shouldEmitAliasDeclaration(node) ? node.name : undefined; const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings); - return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings) : undefined; + return (name || namedBindings) ? factory.updateImportClause(node, node.phaseModifier, name, namedBindings) : undefined; } /** diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 46ff57009e7fa..8187a6ce208d0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -221,7 +221,8 @@ export const enum SyntaxKind { GlobalKeyword, BigIntKeyword, OverrideKeyword, - OfKeyword, // LastKeyword and LastToken and LastContextualKeyword + OfKeyword, + DeferKeyword, // LastKeyword and LastToken and LastContextualKeyword // Parse tree nodes @@ -461,7 +462,7 @@ export const enum SyntaxKind { FirstReservedWord = BreakKeyword, LastReservedWord = WithKeyword, FirstKeyword = BreakKeyword, - LastKeyword = OfKeyword, + LastKeyword = DeferKeyword, FirstFutureReservedWord = ImplementsKeyword, LastFutureReservedWord = YieldKeyword, FirstTypeNode = TypePredicate, @@ -486,7 +487,7 @@ export const enum SyntaxKind { FirstJSDocTagNode = JSDocTag, LastJSDocTagNode = JSDocImportTag, /** @internal */ FirstContextualKeyword = AbstractKeyword, - /** @internal */ LastContextualKeyword = OfKeyword, + /** @internal */ LastContextualKeyword = DeferKeyword, } export type TriviaSyntaxKind = @@ -598,6 +599,7 @@ export type KeywordSyntaxKind = | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword + | SyntaxKind.DeferKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword @@ -3710,11 +3712,14 @@ export type NamedExportBindings = export interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - readonly isTypeOnly: boolean; + /** @deprecated */ readonly isTypeOnly: boolean | "hello"; + readonly phaseModifier: undefined | ImportPhaseModifier; readonly name?: Identifier; // Default binding readonly namedBindings?: NamedImportBindings; } +export type ImportPhaseModifier = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; + /** @deprecated */ export type AssertionKey = ImportAttributeName; @@ -9023,8 +9028,12 @@ export interface NodeFactory { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; - updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createImportClause(phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + // eslint-disable-next-line @typescript-eslint/unified-signatures -- Cannot unify due to the @deprecated tag + /** @deprecated */ createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + // eslint-disable-next-line @typescript-eslint/unified-signatures -- Cannot unify due to the @deprecated tag + /** @deprecated */ updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ createAssertEntry(name: AssertionKey, value: Expression): AssertEntry; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index debbf655c9947..30a949a5f5fc3 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -10909,10 +10909,11 @@ export function isTypeDeclaration(node: Node): node is TypeParameterDeclaration case SyntaxKind.JSDocEnumTag: return true; case SyntaxKind.ImportClause: - return (node as ImportClause).isTypeOnly; + return (node as ImportClause).phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ImportSpecifier: + return (node as ImportSpecifier).parent.parent.phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ExportSpecifier: - return (node as ImportSpecifier | ExportSpecifier).parent.parent.isTypeOnly; + return (node as ExportSpecifier).parent.parent.isTypeOnly; default: return false; } diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 02623678a0cf0..36eba18db07ba 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1534,12 +1534,13 @@ export function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | export function isTypeOnlyImportDeclaration(node: Node): node is TypeOnlyImportDeclaration { switch (node.kind) { case SyntaxKind.ImportSpecifier: - return (node as ImportSpecifier).isTypeOnly || (node as ImportSpecifier).parent.parent.isTypeOnly; + return (node as ImportSpecifier).isTypeOnly || (node as ImportSpecifier).parent.parent.phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.NamespaceImport: - return (node as NamespaceImport).parent.isTypeOnly; + return (node as NamespaceImport).parent.phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ImportClause: + return (node as ImportClause).phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ImportEqualsDeclaration: - return (node as ImportClause | ImportEqualsDeclaration).isTypeOnly; + return (node as ImportEqualsDeclaration).isTypeOnly; } return false; } diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index dbd49379e5750..d1aee94bc6e1b 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1549,7 +1549,7 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.ImportClause]: function visitEachChildOfImportClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateImportClause( node, - node.isTypeOnly, + node.phaseModifier, nodeVisitor(node.name, visitor, isIdentifier), nodeVisitor(node.namedBindings, visitor, isNamedImportBindings), ); diff --git a/src/services/codefixes/convertToTypeOnlyImport.ts b/src/services/codefixes/convertToTypeOnlyImport.ts index 3fdc81f3e4bbb..a5f2b191c36ae 100644 --- a/src/services/codefixes/convertToTypeOnlyImport.ts +++ b/src/services/codefixes/convertToTypeOnlyImport.ts @@ -125,13 +125,13 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de changes.replaceNodeWithNodes(sourceFile, declaration, [ factory.createImportDeclaration( getSynthesizedDeepClones(declaration.modifiers, /*includeTrivia*/ true), - factory.createImportClause(/*isTypeOnly*/ true, getSynthesizedDeepClone(importClause.name, /*includeTrivia*/ true), /*namedBindings*/ undefined), + factory.createImportClause(SyntaxKind.TypeKeyword, getSynthesizedDeepClone(importClause.name, /*includeTrivia*/ true), /*namedBindings*/ undefined), getSynthesizedDeepClone(declaration.moduleSpecifier, /*includeTrivia*/ true), getSynthesizedDeepClone(declaration.attributes, /*includeTrivia*/ true), ), factory.createImportDeclaration( getSynthesizedDeepClones(declaration.modifiers, /*includeTrivia*/ true), - factory.createImportClause(/*isTypeOnly*/ true, /*name*/ undefined, getSynthesizedDeepClone(importClause.namedBindings, /*includeTrivia*/ true)), + factory.createImportClause(SyntaxKind.TypeKeyword, /*name*/ undefined, getSynthesizedDeepClone(importClause.namedBindings, /*includeTrivia*/ true)), getSynthesizedDeepClone(declaration.moduleSpecifier, /*includeTrivia*/ true), getSynthesizedDeepClone(declaration.attributes, /*includeTrivia*/ true), ), @@ -144,7 +144,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de sameMap(importClause.namedBindings.elements, e => factory.updateImportSpecifier(e, /*isTypeOnly*/ false, e.propertyName, e.name)), ) : importClause.namedBindings; - const importDeclaration = factory.updateImportDeclaration(declaration, declaration.modifiers, factory.updateImportClause(importClause, /*isTypeOnly*/ true, importClause.name, newNamedBindings), declaration.moduleSpecifier, declaration.attributes); + const importDeclaration = factory.updateImportDeclaration(declaration, declaration.modifiers, factory.updateImportClause(importClause, SyntaxKind.TypeKeyword, importClause.name, newNamedBindings), declaration.moduleSpecifier, declaration.attributes); changes.replaceNode(sourceFile, declaration, importDeclaration); } } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index a1537c8bde5b7..8a06f8dd3ce07 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -622,7 +622,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog declaration.importClause!, factory.updateImportClause( declaration.importClause!, - declaration.importClause!.isTypeOnly, + declaration.importClause!.phaseModifier, declaration.importClause!.name, /*namedBindings*/ undefined, ), @@ -715,7 +715,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog d.modifiers, d.importClause && factory.updateImportClause( d.importClause, - d.importClause.isTypeOnly, + d.importClause.phaseModifier, verbatimImports.has(d.importClause) ? d.importClause.name : undefined, verbatimImports.has(d.importClause.namedBindings as NamespaceImport) ? d.importClause.namedBindings as NamespaceImport : @@ -2079,7 +2079,7 @@ function getNewImports( : factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - shouldUseTypeOnly(namespaceLikeImport, preferences), + shouldUseTypeOnly(namespaceLikeImport, preferences) ? SyntaxKind.TypeKeyword : undefined, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(namespaceLikeImport.name)), ), diff --git a/src/services/codefixes/requireInTs.ts b/src/services/codefixes/requireInTs.ts index 500a88aad8999..b627fbbc153ec 100644 --- a/src/services/codefixes/requireInTs.ts +++ b/src/services/codefixes/requireInTs.ts @@ -61,7 +61,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, in statement, defaultImportName && !allowSyntheticDefaults ? factory.createImportEqualsDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, defaultImportName, factory.createExternalModuleReference(moduleSpecifier)) - : factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, namedImports), moduleSpecifier, /*attributes*/ undefined), + : factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*phaseModifier*/ undefined, defaultImportName, namedImports), moduleSpecifier, /*attributes*/ undefined), ); } diff --git a/src/services/codefixes/splitTypeOnlyImport.ts b/src/services/codefixes/splitTypeOnlyImport.ts index 967d6fc837c10..70267cae3ada9 100644 --- a/src/services/codefixes/splitTypeOnlyImport.ts +++ b/src/services/codefixes/splitTypeOnlyImport.ts @@ -51,7 +51,7 @@ function splitTypeOnlyImport(changes: textChanges.ChangeTracker, importDeclarati factory.updateImportDeclaration( importDeclaration, importDeclaration.modifiers, - factory.updateImportClause(importClause, importClause.isTypeOnly, importClause.name, /*namedBindings*/ undefined), + factory.updateImportClause(importClause, importClause.phaseModifier, importClause.name, /*namedBindings*/ undefined), importDeclaration.moduleSpecifier, importDeclaration.attributes, ), @@ -62,7 +62,7 @@ function splitTypeOnlyImport(changes: textChanges.ChangeTracker, importDeclarati importDeclaration, factory.createImportDeclaration( /*modifiers*/ undefined, - factory.updateImportClause(importClause, importClause.isTypeOnly, /*name*/ undefined, importClause.namedBindings), + factory.updateImportClause(importClause, importClause.phaseModifier, /*name*/ undefined, importClause.namedBindings), importDeclaration.moduleSpecifier, importDeclaration.attributes, ), diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 1508ba7672d5e..e1343a61d4471 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -639,7 +639,7 @@ function updateImportDeclarationAndClause( return factory.updateImportDeclaration( importDeclaration, importDeclaration.modifiers, - factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.isTypeOnly, name, namedBindings), // TODO: GH#18217 + factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.phaseModifier, name, namedBindings), // TODO: GH#18217 importDeclaration.moduleSpecifier, importDeclaration.attributes, ); diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index 1b21d2d5beb02..a628c77460425 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -290,5 +290,5 @@ function createImport(node: ImportDeclaration, defaultImportName: Identifier | u } function createImportClause(defaultImportName: Identifier | undefined, elements: readonly ImportSpecifier[] | undefined) { - return factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined); + return factory.createImportClause(/*phaseModifier*/ undefined, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined); } diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 6245fe4903dcc..a894c3fdcb963 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -423,7 +423,7 @@ function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: case SyntaxKind.ImportDeclaration: return factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId)), + factory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId)), newModuleString, /*attributes*/ undefined, ); @@ -645,7 +645,7 @@ function filterImport(i: SupportedImport, moduleSpecifier: StringLiteralLike, ke const defaultImport = clause.name && keep(clause.name) ? clause.name : undefined; const namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep); return defaultImport || namedBindings - ? factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(clause.isTypeOnly, defaultImport, namedBindings), getSynthesizedDeepClone(moduleSpecifier), /*attributes*/ undefined) + ? factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(clause.phaseModifier, defaultImport, namedBindings), getSynthesizedDeepClone(moduleSpecifier), /*attributes*/ undefined) : undefined; } case SyntaxKind.ImportEqualsDeclaration: diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0f7b99250111f..f8f4a5b705745 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2497,7 +2497,7 @@ export function makeImport(defaultImport: Identifier | undefined, namedImports: return factory.createImportDeclaration( /*modifiers*/ undefined, defaultImport || namedImports - ? factory.createImportClause(!!isTypeOnly, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined) + ? factory.createImportClause(isTypeOnly ? SyntaxKind.TypeKeyword : undefined, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined) : undefined, typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier, /*attributes*/ undefined, diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 4c4f84790ea63..624ef1ecc3ea4 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -342,7 +342,7 @@ describe("unittests:: TransformAPI", () => { const importStar = ts.factory.createImportDeclaration( /*modifiers*/ undefined, /*importClause*/ ts.factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, ts.factory.createNamespaceImport(ts.factory.createIdentifier("i0")), ), diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json index 817598cb1e86e..6419e4dc7fee7 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json @@ -26,6 +26,7 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "name": { "kind": "Identifier", "pos": 16, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json index d11fa4eb24320..3094ffd460fd6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json @@ -26,6 +26,7 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "namedBindings": { "kind": "NamedImports", "pos": 16, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json index a34c07e9983a9..8352b03a73522 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json @@ -26,6 +26,7 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "namedBindings": { "kind": "NamespaceImport", "pos": 16, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json index e60e392ffb8eb..a681ea5634d28 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json @@ -27,6 +27,7 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "namedBindings": { "kind": "NamespaceImport", "pos": 16, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 11a12e97d4b2e..bc50ed0a973a3 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3837,203 +3837,204 @@ declare namespace ts { BigIntKeyword = 163, OverrideKeyword = 164, OfKeyword = 165, - QualifiedName = 166, - ComputedPropertyName = 167, - TypeParameter = 168, - Parameter = 169, - Decorator = 170, - PropertySignature = 171, - PropertyDeclaration = 172, - MethodSignature = 173, - MethodDeclaration = 174, - ClassStaticBlockDeclaration = 175, - Constructor = 176, - GetAccessor = 177, - SetAccessor = 178, - CallSignature = 179, - ConstructSignature = 180, - IndexSignature = 181, - TypePredicate = 182, - TypeReference = 183, - FunctionType = 184, - ConstructorType = 185, - TypeQuery = 186, - TypeLiteral = 187, - ArrayType = 188, - TupleType = 189, - OptionalType = 190, - RestType = 191, - UnionType = 192, - IntersectionType = 193, - ConditionalType = 194, - InferType = 195, - ParenthesizedType = 196, - ThisType = 197, - TypeOperator = 198, - IndexedAccessType = 199, - MappedType = 200, - LiteralType = 201, - NamedTupleMember = 202, - TemplateLiteralType = 203, - TemplateLiteralTypeSpan = 204, - ImportType = 205, - ObjectBindingPattern = 206, - ArrayBindingPattern = 207, - BindingElement = 208, - ArrayLiteralExpression = 209, - ObjectLiteralExpression = 210, - PropertyAccessExpression = 211, - ElementAccessExpression = 212, - CallExpression = 213, - NewExpression = 214, - TaggedTemplateExpression = 215, - TypeAssertionExpression = 216, - ParenthesizedExpression = 217, - FunctionExpression = 218, - ArrowFunction = 219, - DeleteExpression = 220, - TypeOfExpression = 221, - VoidExpression = 222, - AwaitExpression = 223, - PrefixUnaryExpression = 224, - PostfixUnaryExpression = 225, - BinaryExpression = 226, - ConditionalExpression = 227, - TemplateExpression = 228, - YieldExpression = 229, - SpreadElement = 230, - ClassExpression = 231, - OmittedExpression = 232, - ExpressionWithTypeArguments = 233, - AsExpression = 234, - NonNullExpression = 235, - MetaProperty = 236, - SyntheticExpression = 237, - SatisfiesExpression = 238, - TemplateSpan = 239, - SemicolonClassElement = 240, - Block = 241, - EmptyStatement = 242, - VariableStatement = 243, - ExpressionStatement = 244, - IfStatement = 245, - DoStatement = 246, - WhileStatement = 247, - ForStatement = 248, - ForInStatement = 249, - ForOfStatement = 250, - ContinueStatement = 251, - BreakStatement = 252, - ReturnStatement = 253, - WithStatement = 254, - SwitchStatement = 255, - LabeledStatement = 256, - ThrowStatement = 257, - TryStatement = 258, - DebuggerStatement = 259, - VariableDeclaration = 260, - VariableDeclarationList = 261, - FunctionDeclaration = 262, - ClassDeclaration = 263, - InterfaceDeclaration = 264, - TypeAliasDeclaration = 265, - EnumDeclaration = 266, - ModuleDeclaration = 267, - ModuleBlock = 268, - CaseBlock = 269, - NamespaceExportDeclaration = 270, - ImportEqualsDeclaration = 271, - ImportDeclaration = 272, - ImportClause = 273, - NamespaceImport = 274, - NamedImports = 275, - ImportSpecifier = 276, - ExportAssignment = 277, - ExportDeclaration = 278, - NamedExports = 279, - NamespaceExport = 280, - ExportSpecifier = 281, - MissingDeclaration = 282, - ExternalModuleReference = 283, - JsxElement = 284, - JsxSelfClosingElement = 285, - JsxOpeningElement = 286, - JsxClosingElement = 287, - JsxFragment = 288, - JsxOpeningFragment = 289, - JsxClosingFragment = 290, - JsxAttribute = 291, - JsxAttributes = 292, - JsxSpreadAttribute = 293, - JsxExpression = 294, - JsxNamespacedName = 295, - CaseClause = 296, - DefaultClause = 297, - HeritageClause = 298, - CatchClause = 299, - ImportAttributes = 300, - ImportAttribute = 301, - /** @deprecated */ AssertClause = 300, - /** @deprecated */ AssertEntry = 301, - /** @deprecated */ ImportTypeAssertionContainer = 302, - PropertyAssignment = 303, - ShorthandPropertyAssignment = 304, - SpreadAssignment = 305, - EnumMember = 306, - SourceFile = 307, - Bundle = 308, - JSDocTypeExpression = 309, - JSDocNameReference = 310, - JSDocMemberName = 311, - JSDocAllType = 312, - JSDocUnknownType = 313, - JSDocNullableType = 314, - JSDocNonNullableType = 315, - JSDocOptionalType = 316, - JSDocFunctionType = 317, - JSDocVariadicType = 318, - JSDocNamepathType = 319, - JSDoc = 320, + DeferKeyword = 166, + QualifiedName = 167, + ComputedPropertyName = 168, + TypeParameter = 169, + Parameter = 170, + Decorator = 171, + PropertySignature = 172, + PropertyDeclaration = 173, + MethodSignature = 174, + MethodDeclaration = 175, + ClassStaticBlockDeclaration = 176, + Constructor = 177, + GetAccessor = 178, + SetAccessor = 179, + CallSignature = 180, + ConstructSignature = 181, + IndexSignature = 182, + TypePredicate = 183, + TypeReference = 184, + FunctionType = 185, + ConstructorType = 186, + TypeQuery = 187, + TypeLiteral = 188, + ArrayType = 189, + TupleType = 190, + OptionalType = 191, + RestType = 192, + UnionType = 193, + IntersectionType = 194, + ConditionalType = 195, + InferType = 196, + ParenthesizedType = 197, + ThisType = 198, + TypeOperator = 199, + IndexedAccessType = 200, + MappedType = 201, + LiteralType = 202, + NamedTupleMember = 203, + TemplateLiteralType = 204, + TemplateLiteralTypeSpan = 205, + ImportType = 206, + ObjectBindingPattern = 207, + ArrayBindingPattern = 208, + BindingElement = 209, + ArrayLiteralExpression = 210, + ObjectLiteralExpression = 211, + PropertyAccessExpression = 212, + ElementAccessExpression = 213, + CallExpression = 214, + NewExpression = 215, + TaggedTemplateExpression = 216, + TypeAssertionExpression = 217, + ParenthesizedExpression = 218, + FunctionExpression = 219, + ArrowFunction = 220, + DeleteExpression = 221, + TypeOfExpression = 222, + VoidExpression = 223, + AwaitExpression = 224, + PrefixUnaryExpression = 225, + PostfixUnaryExpression = 226, + BinaryExpression = 227, + ConditionalExpression = 228, + TemplateExpression = 229, + YieldExpression = 230, + SpreadElement = 231, + ClassExpression = 232, + OmittedExpression = 233, + ExpressionWithTypeArguments = 234, + AsExpression = 235, + NonNullExpression = 236, + MetaProperty = 237, + SyntheticExpression = 238, + SatisfiesExpression = 239, + TemplateSpan = 240, + SemicolonClassElement = 241, + Block = 242, + EmptyStatement = 243, + VariableStatement = 244, + ExpressionStatement = 245, + IfStatement = 246, + DoStatement = 247, + WhileStatement = 248, + ForStatement = 249, + ForInStatement = 250, + ForOfStatement = 251, + ContinueStatement = 252, + BreakStatement = 253, + ReturnStatement = 254, + WithStatement = 255, + SwitchStatement = 256, + LabeledStatement = 257, + ThrowStatement = 258, + TryStatement = 259, + DebuggerStatement = 260, + VariableDeclaration = 261, + VariableDeclarationList = 262, + FunctionDeclaration = 263, + ClassDeclaration = 264, + InterfaceDeclaration = 265, + TypeAliasDeclaration = 266, + EnumDeclaration = 267, + ModuleDeclaration = 268, + ModuleBlock = 269, + CaseBlock = 270, + NamespaceExportDeclaration = 271, + ImportEqualsDeclaration = 272, + ImportDeclaration = 273, + ImportClause = 274, + NamespaceImport = 275, + NamedImports = 276, + ImportSpecifier = 277, + ExportAssignment = 278, + ExportDeclaration = 279, + NamedExports = 280, + NamespaceExport = 281, + ExportSpecifier = 282, + MissingDeclaration = 283, + ExternalModuleReference = 284, + JsxElement = 285, + JsxSelfClosingElement = 286, + JsxOpeningElement = 287, + JsxClosingElement = 288, + JsxFragment = 289, + JsxOpeningFragment = 290, + JsxClosingFragment = 291, + JsxAttribute = 292, + JsxAttributes = 293, + JsxSpreadAttribute = 294, + JsxExpression = 295, + JsxNamespacedName = 296, + CaseClause = 297, + DefaultClause = 298, + HeritageClause = 299, + CatchClause = 300, + ImportAttributes = 301, + ImportAttribute = 302, + /** @deprecated */ AssertClause = 301, + /** @deprecated */ AssertEntry = 302, + /** @deprecated */ ImportTypeAssertionContainer = 303, + PropertyAssignment = 304, + ShorthandPropertyAssignment = 305, + SpreadAssignment = 306, + EnumMember = 307, + SourceFile = 308, + Bundle = 309, + JSDocTypeExpression = 310, + JSDocNameReference = 311, + JSDocMemberName = 312, + JSDocAllType = 313, + JSDocUnknownType = 314, + JSDocNullableType = 315, + JSDocNonNullableType = 316, + JSDocOptionalType = 317, + JSDocFunctionType = 318, + JSDocVariadicType = 319, + JSDocNamepathType = 320, + JSDoc = 321, /** @deprecated Use SyntaxKind.JSDoc */ - JSDocComment = 320, - JSDocText = 321, - JSDocTypeLiteral = 322, - JSDocSignature = 323, - JSDocLink = 324, - JSDocLinkCode = 325, - JSDocLinkPlain = 326, - JSDocTag = 327, - JSDocAugmentsTag = 328, - JSDocImplementsTag = 329, - JSDocAuthorTag = 330, - JSDocDeprecatedTag = 331, - JSDocClassTag = 332, - JSDocPublicTag = 333, - JSDocPrivateTag = 334, - JSDocProtectedTag = 335, - JSDocReadonlyTag = 336, - JSDocOverrideTag = 337, - JSDocCallbackTag = 338, - JSDocOverloadTag = 339, - JSDocEnumTag = 340, - JSDocParameterTag = 341, - JSDocReturnTag = 342, - JSDocThisTag = 343, - JSDocTypeTag = 344, - JSDocTemplateTag = 345, - JSDocTypedefTag = 346, - JSDocSeeTag = 347, - JSDocPropertyTag = 348, - JSDocThrowsTag = 349, - JSDocSatisfiesTag = 350, - JSDocImportTag = 351, - SyntaxList = 352, - NotEmittedStatement = 353, - NotEmittedTypeElement = 354, - PartiallyEmittedExpression = 355, - CommaListExpression = 356, - SyntheticReferenceExpression = 357, - Count = 358, + JSDocComment = 321, + JSDocText = 322, + JSDocTypeLiteral = 323, + JSDocSignature = 324, + JSDocLink = 325, + JSDocLinkCode = 326, + JSDocLinkPlain = 327, + JSDocTag = 328, + JSDocAugmentsTag = 329, + JSDocImplementsTag = 330, + JSDocAuthorTag = 331, + JSDocDeprecatedTag = 332, + JSDocClassTag = 333, + JSDocPublicTag = 334, + JSDocPrivateTag = 335, + JSDocProtectedTag = 336, + JSDocReadonlyTag = 337, + JSDocOverrideTag = 338, + JSDocCallbackTag = 339, + JSDocOverloadTag = 340, + JSDocEnumTag = 341, + JSDocParameterTag = 342, + JSDocReturnTag = 343, + JSDocThisTag = 344, + JSDocTypeTag = 345, + JSDocTemplateTag = 346, + JSDocTypedefTag = 347, + JSDocSeeTag = 348, + JSDocPropertyTag = 349, + JSDocThrowsTag = 350, + JSDocSatisfiesTag = 351, + JSDocImportTag = 352, + SyntaxList = 353, + NotEmittedStatement = 354, + NotEmittedTypeElement = 355, + PartiallyEmittedExpression = 356, + CommaListExpression = 357, + SyntheticReferenceExpression = 358, + Count = 359, FirstAssignment = 64, LastAssignment = 79, FirstCompoundAssignment = 65, @@ -4041,15 +4042,15 @@ declare namespace ts { FirstReservedWord = 83, LastReservedWord = 118, FirstKeyword = 83, - LastKeyword = 165, + LastKeyword = 166, FirstFutureReservedWord = 119, LastFutureReservedWord = 127, - FirstTypeNode = 182, - LastTypeNode = 205, + FirstTypeNode = 183, + LastTypeNode = 206, FirstPunctuation = 19, LastPunctuation = 79, FirstToken = 0, - LastToken = 165, + LastToken = 166, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 9, @@ -4058,13 +4059,13 @@ declare namespace ts { LastTemplateToken = 18, FirstBinaryOperator = 30, LastBinaryOperator = 79, - FirstStatement = 243, - LastStatement = 259, - FirstNode = 166, - FirstJSDocNode = 309, - LastJSDocNode = 351, - FirstJSDocTagNode = 327, - LastJSDocTagNode = 351, + FirstStatement = 244, + LastStatement = 260, + FirstNode = 167, + FirstJSDocNode = 310, + LastJSDocNode = 352, + FirstJSDocTagNode = 328, + LastJSDocTagNode = 352, } type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; @@ -4152,6 +4153,7 @@ declare namespace ts { | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword + | SyntaxKind.DeferKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword @@ -5513,10 +5515,12 @@ declare namespace ts { interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - readonly isTypeOnly: boolean; + /** @deprecated */ readonly isTypeOnly: boolean | "hello"; + readonly phaseModifier: undefined | ImportPhaseModifier; readonly name?: Identifier; readonly namedBindings?: NamedImportBindings; } + type ImportPhaseModifier = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; /** @deprecated */ type AssertionKey = ImportAttributeName; /** @deprecated */ @@ -7711,8 +7715,10 @@ declare namespace ts { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; - updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createImportClause(phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + /** @deprecated */ createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + /** @deprecated */ updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ createAssertEntry(name: AssertionKey, value: Expression): AssertEntry; diff --git a/tests/baselines/reference/exportDeferInvalid.errors.txt b/tests/baselines/reference/exportDeferInvalid.errors.txt new file mode 100644 index 0000000000000..21055164ce6d4 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.errors.txt @@ -0,0 +1,31 @@ +b.ts(1,1): error TS1128: Declaration or statement expected. +b.ts(1,8): error TS2304: Cannot find name 'defer'. +b.ts(1,16): error TS2304: Cannot find name 'as'. +b.ts(1,19): error TS1005: ';' expected. +b.ts(1,19): error TS2304: Cannot find name 'ns'. +b.ts(1,22): error TS1434: Unexpected keyword or identifier. +b.ts(1,22): error TS2304: Cannot find name 'from'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (7 errors) ==== + export defer * as ns from "a"; + ~~~~~~ +!!! error TS1128: Declaration or statement expected. + ~~~~~ +!!! error TS2304: Cannot find name 'defer'. + ~~ +!!! error TS2304: Cannot find name 'as'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'ns'. + ~~~~ +!!! error TS1434: Unexpected keyword or identifier. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + \ No newline at end of file diff --git a/tests/baselines/reference/exportDeferInvalid.js b/tests/baselines/reference/exportDeferInvalid.js new file mode 100644 index 0000000000000..8b2e752a22b66 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/exportDeferInvalid.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +export defer * as ns from "a"; + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +defer * as; +ns; +from; +"a"; diff --git a/tests/baselines/reference/exportDeferInvalid.symbols b/tests/baselines/reference/exportDeferInvalid.symbols new file mode 100644 index 0000000000000..ccc6ae0d9a914 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/importDefer/exportDeferInvalid.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === + +export defer * as ns from "a"; + diff --git a/tests/baselines/reference/exportDeferInvalid.types b/tests/baselines/reference/exportDeferInvalid.types new file mode 100644 index 0000000000000..e10299d8b12e7 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/exportDeferInvalid.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +export defer * as ns from "a"; +>defer * as : number +> : ^^^^^^ +>defer : any +> : ^^^ +>as : any +> : ^^^ +>ns : any +> : ^^^ +>from : any +> : ^^^ +>"a" : "a" +> : ^^^ + diff --git a/tests/baselines/reference/importDefaultBindingDefer.js b/tests/baselines/reference/importDefaultBindingDefer.js new file mode 100644 index 0000000000000..aa2e7c26211db --- /dev/null +++ b/tests/baselines/reference/importDefaultBindingDefer.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDefaultBindingDefer.ts] //// + +//// [a.ts] +export default function defer() { + console.log("defer from a"); +} + +//// [b.ts] +import defer from "a"; + +defer(); + +//// [a.js] +export default function defer() { + console.log("defer from a"); +} +//// [b.js] +import defer from "a"; +defer(); diff --git a/tests/baselines/reference/importDefaultBindingDefer.symbols b/tests/baselines/reference/importDefaultBindingDefer.symbols new file mode 100644 index 0000000000000..9c233fcf0bda0 --- /dev/null +++ b/tests/baselines/reference/importDefaultBindingDefer.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDefaultBindingDefer.ts] //// + +=== a.ts === +export default function defer() { +>defer : Symbol(defer, Decl(a.ts, 0, 0)) + + console.log("defer from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer from "a"; +>defer : Symbol(defer, Decl(b.ts, 0, 6)) + +defer(); +>defer : Symbol(defer, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/importDefaultBindingDefer.types b/tests/baselines/reference/importDefaultBindingDefer.types new file mode 100644 index 0000000000000..f647f0914868d --- /dev/null +++ b/tests/baselines/reference/importDefaultBindingDefer.types @@ -0,0 +1,31 @@ +//// [tests/cases/conformance/importDefer/importDefaultBindingDefer.ts] //// + +=== a.ts === +export default function defer() { +>defer : () => void +> : ^^^^^^^^^^ + + console.log("defer from a"); +>console.log("defer from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"defer from a" : "defer from a" +> : ^^^^^^^^^^^^^^ +} + +=== b.ts === +import defer from "a"; +>defer : () => void +> : ^^^^^^^^^^ + +defer(); +>defer() : void +> : ^^^^ +>defer : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferComments.js b/tests/baselines/reference/importDeferComments.js new file mode 100644 index 0000000000000..3e7980dbc1665 --- /dev/null +++ b/tests/baselines/reference/importDeferComments.js @@ -0,0 +1,13 @@ +//// [tests/cases/conformance/importDefer/importDeferComments.ts] //// + +//// [a.ts] +export {}; + +//// [b.ts] +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; + + +//// [a.js] +export {}; +//// [b.js] +export {}; diff --git a/tests/baselines/reference/importDeferComments.symbols b/tests/baselines/reference/importDeferComments.symbols new file mode 100644 index 0000000000000..fec1187392018 --- /dev/null +++ b/tests/baselines/reference/importDeferComments.symbols @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/importDefer/importDeferComments.ts] //// + +=== a.ts === + +export {}; + +=== b.ts === +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; +>aNs : Symbol(aNs, Decl(b.ts, 0, 24)) + diff --git a/tests/baselines/reference/importDeferComments.types b/tests/baselines/reference/importDeferComments.types new file mode 100644 index 0000000000000..6f06fb95216ac --- /dev/null +++ b/tests/baselines/reference/importDeferComments.types @@ -0,0 +1,11 @@ +//// [tests/cases/conformance/importDefer/importDeferComments.ts] //// + +=== a.ts === + +export {}; + +=== b.ts === +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; +>aNs : typeof aNs +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferInvalidDefault.errors.txt b/tests/baselines/reference/importDeferInvalidDefault.errors.txt new file mode 100644 index 0000000000000..f0460162e2025 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.errors.txt @@ -0,0 +1,14 @@ +b.ts(1,14): error TS18058: Default imports aren't allowed for deferred imports. + + +==== a.ts (0 errors) ==== + export default function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import defer foo from "a"; + ~~~ +!!! error TS18058: Default imports aren't allowed for deferred imports. + + foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferInvalidDefault.js b/tests/baselines/reference/importDeferInvalidDefault.js new file mode 100644 index 0000000000000..e0f3491c6329f --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidDefault.ts] //// + +//// [a.ts] +export default function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer foo from "a"; + +foo(); + +//// [a.js] +export default function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer foo from "a"; +foo(); diff --git a/tests/baselines/reference/importDeferInvalidDefault.symbols b/tests/baselines/reference/importDeferInvalidDefault.symbols new file mode 100644 index 0000000000000..dd548fc59340a --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidDefault.ts] //// + +=== a.ts === +export default function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer foo from "a"; +>foo : Symbol(foo, Decl(b.ts, 0, 6)) + +foo(); +>foo : Symbol(foo, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/importDeferInvalidDefault.types b/tests/baselines/reference/importDeferInvalidDefault.types new file mode 100644 index 0000000000000..ae22c6fd8d417 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.types @@ -0,0 +1,31 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidDefault.ts] //// + +=== a.ts === +export default function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer foo from "a"; +>foo : () => void +> : ^^^^^^^^^^ + +foo(); +>foo() : void +> : ^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferInvalidNamed.errors.txt b/tests/baselines/reference/importDeferInvalidNamed.errors.txt new file mode 100644 index 0000000000000..7a72a9edd77b5 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.errors.txt @@ -0,0 +1,14 @@ +b.ts(1,14): error TS18059: Named imports aren't allowed for deferred imports. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import defer { foo } from "a"; + ~ +!!! error TS18059: Named imports aren't allowed for deferred imports. + + foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferInvalidNamed.js b/tests/baselines/reference/importDeferInvalidNamed.js new file mode 100644 index 0000000000000..8f92f52fa0ee5 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidNamed.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer { foo } from "a"; + +foo(); + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer { foo } from "a"; +foo(); diff --git a/tests/baselines/reference/importDeferInvalidNamed.symbols b/tests/baselines/reference/importDeferInvalidNamed.symbols new file mode 100644 index 0000000000000..77f3959cd7e06 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidNamed.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer { foo } from "a"; +>foo : Symbol(foo, Decl(b.ts, 0, 14)) + +foo(); +>foo : Symbol(foo, Decl(b.ts, 0, 14)) + diff --git a/tests/baselines/reference/importDeferInvalidNamed.types b/tests/baselines/reference/importDeferInvalidNamed.types new file mode 100644 index 0000000000000..5568523603e08 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.types @@ -0,0 +1,31 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidNamed.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer { foo } from "a"; +>foo : () => void +> : ^^^^^^^^^^ + +foo(); +>foo() : void +> : ^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt b/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt new file mode 100644 index 0000000000000..f931b4e67d328 --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt @@ -0,0 +1,18 @@ +b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. +b.ts(1,28): error TS2307: Cannot find module 'a' or its corresponding type declarations. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (2 errors) ==== + import defer * as aNs from "a"; + ~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. + ~~~ +!!! error TS2307: Cannot find module 'a' or its corresponding type declarations. + + aNs.foo(); + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.js b/tests/baselines/reference/importDeferMissingModuleESNext.js new file mode 100644 index 0000000000000..60f2c2d9c6d6a --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.js @@ -0,0 +1,25 @@ +//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "a"; + +aNs.foo(); + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = foo; +function foo() { + console.log("foo from a"); +} +//// [b.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var aNs = require("a"); +aNs.foo(); diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.symbols b/tests/baselines/reference/importDeferMissingModuleESNext.symbols new file mode 100644 index 0000000000000..e556f00387bda --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.types b/tests/baselines/reference/importDeferMissingModuleESNext.types new file mode 100644 index 0000000000000..d75d7fd356307 --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : any +> : ^^^ + +aNs.foo(); +>aNs.foo() : any +> : ^^^ +>aNs.foo : any +> : ^^^ +>aNs : any +> : ^^^ +>foo : any +> : ^^^ + diff --git a/tests/baselines/reference/importDeferNamespace.js b/tests/baselines/reference/importDeferNamespace.js new file mode 100644 index 0000000000000..80edab5e81278 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "a"; + +aNs.foo(); + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer * as aNs from "a"; +aNs.foo(); diff --git a/tests/baselines/reference/importDeferNamespace.symbols b/tests/baselines/reference/importDeferNamespace.symbols new file mode 100644 index 0000000000000..115690adecd50 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) +>foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferNamespace.types b/tests/baselines/reference/importDeferNamespace.types new file mode 100644 index 0000000000000..eda2b889f3fd2 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : typeof aNs +> : ^^^^^^^^^^ + +aNs.foo(); +>aNs.foo() : void +> : ^^^^ +>aNs.foo : () => void +> : ^^^^^^^^^^ +>aNs : typeof aNs +> : ^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferTypeConflict1.errors.txt b/tests/baselines/reference/importDeferTypeConflict1.errors.txt new file mode 100644 index 0000000000000..138cfa68e9b36 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.errors.txt @@ -0,0 +1,28 @@ +b.ts(1,19): error TS1005: '=' expected. +b.ts(1,21): error TS2304: Cannot find name 'as'. +b.ts(1,24): error TS1005: ';' expected. +b.ts(1,24): error TS2304: Cannot find name 'ns1'. +b.ts(1,28): error TS1434: Unexpected keyword or identifier. +b.ts(1,28): error TS2304: Cannot find name 'from'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (6 errors) ==== + import type defer * as ns1 from "a"; + ~ +!!! error TS1005: '=' expected. + ~~ +!!! error TS2304: Cannot find name 'as'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'ns1'. + ~~~~ +!!! error TS1434: Unexpected keyword or identifier. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferTypeConflict1.js b/tests/baselines/reference/importDeferTypeConflict1.js new file mode 100644 index 0000000000000..0577f6a08cb7c --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict1.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import type defer * as ns1 from "a"; + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] + * as; +ns1; +from; +"a"; diff --git a/tests/baselines/reference/importDeferTypeConflict1.symbols b/tests/baselines/reference/importDeferTypeConflict1.symbols new file mode 100644 index 0000000000000..961367f241e5b --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict1.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import type defer * as ns1 from "a"; +>defer : Symbol(defer, Decl(b.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferTypeConflict1.types b/tests/baselines/reference/importDeferTypeConflict1.types new file mode 100644 index 0000000000000..ea2a7ef944685 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.types @@ -0,0 +1,39 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict1.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import type defer * as ns1 from "a"; +>defer : any +> : ^^^ +> : any +> : ^^^ +>* as : number +> : ^^^^^^ +> : any +> : ^^^ +>as : any +> : ^^^ +>ns1 : any +> : ^^^ +>from : any +> : ^^^ +>"a" : "a" +> : ^^^ + diff --git a/tests/baselines/reference/importDeferTypeConflict2.errors.txt b/tests/baselines/reference/importDeferTypeConflict2.errors.txt new file mode 100644 index 0000000000000..ae646749a1748 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.errors.txt @@ -0,0 +1,31 @@ +b.ts(1,14): error TS18058: Default imports aren't allowed for deferred imports. +b.ts(1,19): error TS1005: 'from' expected. +b.ts(1,19): error TS1141: String literal expected. +b.ts(1,24): error TS1005: ';' expected. +b.ts(1,24): error TS2304: Cannot find name 'ns1'. +b.ts(1,28): error TS1434: Unexpected keyword or identifier. +b.ts(1,28): error TS2304: Cannot find name 'from'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (7 errors) ==== + import defer type * as ns1 from "a"; + ~~~~ +!!! error TS18058: Default imports aren't allowed for deferred imports. + ~ +!!! error TS1005: 'from' expected. + ~~~~ +!!! error TS1141: String literal expected. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'ns1'. + ~~~~ +!!! error TS1434: Unexpected keyword or identifier. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferTypeConflict2.js b/tests/baselines/reference/importDeferTypeConflict2.js new file mode 100644 index 0000000000000..1c06d70469687 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict2.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer type * as ns1 from "a"; + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +ns1; +from; +"a"; +export {}; diff --git a/tests/baselines/reference/importDeferTypeConflict2.symbols b/tests/baselines/reference/importDeferTypeConflict2.symbols new file mode 100644 index 0000000000000..ea867e3cfdc51 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict2.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer type * as ns1 from "a"; +>type : Symbol(type, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/importDeferTypeConflict2.types b/tests/baselines/reference/importDeferTypeConflict2.types new file mode 100644 index 0000000000000..bbcc915ad31bc --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.types @@ -0,0 +1,37 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict2.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer type * as ns1 from "a"; +>type : any +> : ^^^ +>* as : number +> : ^^^^^^ +> : any +> : ^^^ +>as : any +> : ^^^ +>ns1 : any +> : ^^^ +>from : any +> : ^^^ +>"a" : "a" +> : ^^^ + diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff index e85d3dac9427d..f9a6bdcff52dc 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeErrors -@@ -214,7 +214,7 @@ +@@ -216,7 +216,7 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff index d54b75b0af7d6..93dd08f83a579 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeErrors -@@ -214,6 +214,6 @@ +@@ -216,6 +216,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff index 894c809d38c7e..8e9b6490c335e 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeInfo -@@ -214,7 +214,7 @@ +@@ -216,7 +216,7 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff index 0c2bff5a4677e..5a838cf8451b4 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeInfo -@@ -88,52 +88,9 @@ +@@ -89,52 +89,9 @@ "pos": 69, "end": 69, "hasTrailingComma": false, @@ -55,7 +55,7 @@ "length": 2, "pos": 0, "end": 70, -@@ -214,6 +171,6 @@ +@@ -216,6 +173,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff index 3a1028bb08254..8d86662fa7f32 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseNone -@@ -88,52 +88,9 @@ +@@ -89,52 +89,9 @@ "pos": 69, "end": 69, "hasTrailingComma": false, @@ -55,7 +55,7 @@ "length": 2, "pos": 0, "end": 70, -@@ -214,7 +171,6 @@ +@@ -216,7 +173,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff index 41135dc2495ba..c2edc9324a2a0 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseNone -@@ -88,52 +88,9 @@ +@@ -89,52 +89,9 @@ "pos": 69, "end": 69, "hasTrailingComma": false, @@ -55,7 +55,7 @@ "length": 2, "pos": 0, "end": 70, -@@ -214,6 +171,6 @@ +@@ -216,6 +173,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/cases/conformance/importDefer/exportDeferInvalid.ts b/tests/cases/conformance/importDefer/exportDeferInvalid.ts new file mode 100644 index 0000000000000..0d0dc587bf2bd --- /dev/null +++ b/tests/cases/conformance/importDefer/exportDeferInvalid.ts @@ -0,0 +1,8 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +export defer * as ns from "a"; diff --git a/tests/cases/conformance/importDefer/importDefaultBindingDefer.ts b/tests/cases/conformance/importDefer/importDefaultBindingDefer.ts new file mode 100644 index 0000000000000..bcbacf6c13a53 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDefaultBindingDefer.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export default function defer() { + console.log("defer from a"); +} + +// @filename: b.ts +import defer from "a"; + +defer(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferComments.ts b/tests/cases/conformance/importDefer/importDeferComments.ts new file mode 100644 index 0000000000000..ce480f94260af --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferComments.ts @@ -0,0 +1,6 @@ +// @module: esnext +// @filename: a.ts +export {}; + +// @filename: b.ts +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; diff --git a/tests/cases/conformance/importDefer/importDeferInvalidDefault.ts b/tests/cases/conformance/importDefer/importDeferInvalidDefault.ts new file mode 100644 index 0000000000000..d3f02c8d13926 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferInvalidDefault.ts @@ -0,0 +1,11 @@ + +// @module: esnext +// @filename: a.ts +export default function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer foo from "a"; + +foo(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferInvalidNamed.ts b/tests/cases/conformance/importDefer/importDeferInvalidNamed.ts new file mode 100644 index 0000000000000..078f5a132223f --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferInvalidNamed.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer { foo } from "a"; + +foo(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts b/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts new file mode 100644 index 0000000000000..937a0bcfa80c6 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts @@ -0,0 +1,9 @@ +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer * as aNs from "a"; + +aNs.foo(); diff --git a/tests/cases/conformance/importDefer/importDeferNamespace.ts b/tests/cases/conformance/importDefer/importDeferNamespace.ts new file mode 100644 index 0000000000000..c5b0e08d1fd56 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferNamespace.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer * as aNs from "a"; + +aNs.foo(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferTypeConflict1.ts b/tests/cases/conformance/importDefer/importDeferTypeConflict1.ts new file mode 100644 index 0000000000000..5cf5ef7c544ae --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferTypeConflict1.ts @@ -0,0 +1,8 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import type defer * as ns1 from "a"; diff --git a/tests/cases/conformance/importDefer/importDeferTypeConflict2.ts b/tests/cases/conformance/importDefer/importDeferTypeConflict2.ts new file mode 100644 index 0000000000000..a12aa3529e3a3 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferTypeConflict2.ts @@ -0,0 +1,8 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer type * as ns1 from "a";