diff --git a/scripts/build/gulp-typescript-oop/protocol.js b/scripts/build/gulp-typescript-oop/protocol.js index 58e60b058d4..714b94f22a1 100644 --- a/scripts/build/gulp-typescript-oop/protocol.js +++ b/scripts/build/gulp-typescript-oop/protocol.js @@ -140,7 +140,7 @@ function diagnosticFromJson(json, host) { category: json.category, code: json.code, source: json.source, - relatedInformation: json.relatedInformation && json.relatedInformation.map(diagnosticRelatedInformationFromJson, host) + relatedInformation: json.relatedInformation && json.relatedInformation.map(json => diagnosticRelatedInformationFromJson(json, host)) }); } exports.diagnosticFromJson = diagnosticFromJson; @@ -169,7 +169,9 @@ function diagnosticRelatedInformationFromJson(json, host) { file: json.file && sourceFileFromJson(json.file, host), start: json.start, length: json.length, - messageText: json.messageText + messageText: json.messageText, + category: json.category, + code: json.code }; } exports.diagnosticRelatedInformationFromJson = diagnosticRelatedInformationFromJson; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f2f6ad93562..d3974da9930 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13900,6 +13900,18 @@ namespace ts { return flow.id; } + function typeMaybeAssignableTo(source: Type, target: Type) { + if (!(source.flags & TypeFlags.Union)) { + return isTypeAssignableTo(source, target); + } + for (const t of (source).types) { + if (isTypeAssignableTo(t, target)) { + return true; + } + } + return false; + } + // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable. // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean, // we remove type string. @@ -13908,8 +13920,12 @@ namespace ts { if (assignedType.flags & TypeFlags.Never) { return assignedType; } - const reducedType = filterType(declaredType, t => isTypeComparableTo(assignedType, t)); - if (!(reducedType.flags & TypeFlags.Never)) { + const reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t)); + // Our crude heuristic produces an invalid result in some cases: see GH#26130. + // For now, when that happens, we give up and don't narrow at all. (This also + // means we'll never narrow for erroneous assignments where the assigned type + // is not assignable to the declared type.) + if (isTypeAssignableTo(assignedType, reducedType)) { return reducedType; } } @@ -19442,11 +19458,13 @@ namespace ts { const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call); if (callSignatures.length) { const signature = resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp); - if (signature.declaration && !isJavascriptConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) { - error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword); - } - if (getThisTypeOfSignature(signature) === voidType) { - error(node, Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void); + if (!noImplicitAny) { + if (signature.declaration && !isJavascriptConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) { + error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword); + } + if (getThisTypeOfSignature(signature) === voidType) { + error(node, Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void); + } } return signature; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index badbfc4fa3f..613fe7f5c84 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2593,14 +2593,14 @@ namespace ts { } function emitSyntheticTripleSlashReferencesIfNeeded(node: Bundle) { - emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || []); + emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []); } function emitTripleSlashDirectivesIfNeeded(node: SourceFile) { - if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives); + if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives); } - function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray, types: ReadonlyArray) { + function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray, types: ReadonlyArray, libs: ReadonlyArray) { if (hasNoDefaultLib) { write(`/// `); writeLine(); @@ -2628,6 +2628,10 @@ namespace ts { write(`/// `); writeLine(); } + for (const directive of libs) { + write(`/// `); + writeLine(); + } } function emitSourceFileWorker(node: SourceFile) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index d52025f5a30..abbc935cf65 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1237,6 +1237,7 @@ namespace ts { getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, + getLibFileFromReference: program.getLibFileFromReference, isSourceFileFromExternalLibrary, writeFile: writeFileCallback || ( (fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)), diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 2fa093128bc..063b5f1cd1d 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -33,7 +33,7 @@ namespace ts { let needsScopeFixMarker = false; let resultHasScopeMarker = false; let enclosingDeclaration: Node; - let necessaryTypeRefernces: Map | undefined; + let necessaryTypeReferences: Map | undefined; let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined; let lateStatementReplacementMap: Map>; let suppressNewDiagnosticContexts: boolean; @@ -53,6 +53,7 @@ namespace ts { let currentSourceFile: SourceFile; let refs: Map; + let libs: Map; const resolver = context.getEmitResolver(); const options = context.getCompilerOptions(); const newLine = getNewLineCharacter(options); @@ -63,9 +64,9 @@ namespace ts { if (!typeReferenceDirectives) { return; } - necessaryTypeRefernces = necessaryTypeRefernces || createMap(); + necessaryTypeReferences = necessaryTypeReferences || createMap(); for (const ref of typeReferenceDirectives) { - necessaryTypeRefernces.set(ref, true); + necessaryTypeReferences.set(ref, true); } } @@ -163,6 +164,7 @@ namespace ts { if (node.kind === SyntaxKind.Bundle) { isBundledEmit = true; refs = createMap(); + libs = createMap(); let hasNoDefaultLib = false; const bundle = createBundle(map(node.sourceFiles, sourceFile => { @@ -177,6 +179,7 @@ namespace ts { needsScopeFixMarker = false; resultHasScopeMarker = false; collectReferences(sourceFile, refs); + collectLibs(sourceFile, libs); if (isExternalModule(sourceFile)) { resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules) needsDeclare = false; @@ -200,6 +203,7 @@ namespace ts { })); bundle.syntheticFileReferences = []; bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences(); + bundle.syntheticLibReferences = getLibReferences(); bundle.hasNoDefaultLib = hasNoDefaultLib; const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath); @@ -219,8 +223,9 @@ namespace ts { suppressNewDiagnosticContexts = false; lateMarkedStatements = undefined; lateStatementReplacementMap = createMap(); - necessaryTypeRefernces = undefined; + necessaryTypeReferences = undefined; refs = collectReferences(currentSourceFile, createMap()); + libs = collectLibs(currentSourceFile, createMap()); const references: FileReference[] = []; const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!)); const referenceVisitor = mapReferencesIntoArray(references, outputFilePath); @@ -231,12 +236,16 @@ namespace ts { if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) { combinedStatements = setTextRange(createNodeArray([...combinedStatements, createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined)]), combinedStatements); } - const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib); + const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences()); updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit; return updated; + function getLibReferences() { + return map(arrayFrom(libs.keys()), lib => ({ fileName: lib, pos: -1, end: -1 })); + } + function getFileReferencesForUsedTypeReferences() { - return necessaryTypeRefernces ? mapDefined(arrayFrom(necessaryTypeRefernces.keys()), getFileReferenceForTypeName) : []; + return necessaryTypeReferences ? mapDefined(arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForTypeName) : []; } function getFileReferenceForTypeName(typeName: string): FileReference | undefined { @@ -297,6 +306,16 @@ namespace ts { return ret; } + function collectLibs(sourceFile: SourceFile, ret: Map) { + forEach(sourceFile.libReferenceDirectives, ref => { + const lib = host.getLibFileFromReference(ref); + if (lib) { + ret.set(ref.fileName.toLocaleLowerCase(), true); + } + }); + return ret; + } + function filterBindingPatternInitializers(name: BindingName) { if (name.kind === SyntaxKind.Identifier) { return name; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8696512071d..4330a776d04 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2648,6 +2648,7 @@ namespace ts { sourceFiles: ReadonlyArray; /* @internal */ syntheticFileReferences?: ReadonlyArray; /* @internal */ syntheticTypeReferences?: ReadonlyArray; + /* @internal */ syntheticLibReferences?: ReadonlyArray; /* @internal */ hasNoDefaultLib?: boolean; } @@ -5074,6 +5075,7 @@ namespace ts { /* @internal */ isSourceFileFromExternalLibrary(file: SourceFile): boolean; + getLibFileFromReference(ref: FileReference): SourceFile | undefined; getCommonSourceDirectory(): string; getCanonicalFileName(fileName: string): string; diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts index ee99aed930c..7a21cebb4f3 100644 --- a/src/services/documentRegistry.ts +++ b/src/services/documentRegistry.ts @@ -184,7 +184,7 @@ namespace ts { const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true); let entry = bucket.get(path); - const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target; + const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target || ScriptTarget.ES5; if (!entry && externalCache) { const sourceFile = externalCache.getDocument(key, path); if (sourceFile) { @@ -199,7 +199,7 @@ namespace ts { if (!entry) { // Have never seen this file with these settings. Create a new source file for it. - const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget!, version, /*setNodeParents*/ false, scriptKind); // TODO: GH#18217 + const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind); if (externalCache) { externalCache.setDocument(key, path, sourceFile); } diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index 3b400fd0c2a..f39b8080ed2 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -319,38 +319,6 @@ interface String { charAt: any; } interface Array {}` }; - const newLineCharacter = "\n"; - const formatOptions: FormatCodeSettings = { - indentSize: 4, - tabSize: 4, - newLineCharacter, - convertTabsToSpaces: true, - indentStyle: IndentStyle.Smart, - insertSpaceAfterConstructor: false, - insertSpaceAfterCommaDelimiter: true, - insertSpaceAfterSemicolonInForStatements: true, - insertSpaceBeforeAndAfterBinaryOperators: true, - insertSpaceAfterKeywordsInControlFlowStatements: true, - insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, - insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, - insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, - insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, - insertSpaceBeforeFunctionParenthesis: false, - placeOpenBraceOnNewLineForFunctions: false, - placeOpenBraceOnNewLineForControlBlocks: false, - }; - - const notImplementedHost: LanguageServiceHost = { - getCompilationSettings: notImplemented, - getScriptFileNames: notImplemented, - getScriptVersion: notImplemented, - getScriptSnapshot: notImplemented, - getDefaultLibFileName: notImplemented, - getCurrentDirectory: notImplemented, - }; - function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) { const t = getTest(text); const selectionRange = t.ranges.get("selection")!; @@ -389,7 +357,7 @@ interface Array {}` cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse }, preferences: emptyOptions, host: notImplementedHost, - formatContext: formatting.getFormatContext(formatOptions) + formatContext: formatting.getFormatContext(testFormatOptions) }; const diagnostics = languageService.getSuggestionDiagnostics(f.path); diff --git a/src/testRunner/unittests/extractTestHelpers.ts b/src/testRunner/unittests/extractTestHelpers.ts index 1b3d00362ec..6e46c1304ab 100644 --- a/src/testRunner/unittests/extractTestHelpers.ts +++ b/src/testRunner/unittests/extractTestHelpers.ts @@ -86,7 +86,7 @@ namespace ts { placeOpenBraceOnNewLineForControlBlocks: false, }; - const notImplementedHost: LanguageServiceHost = { + export const notImplementedHost: LanguageServiceHost = { getCompilationSettings: notImplemented, getScriptFileNames: notImplemented, getScriptVersion: notImplemented, diff --git a/tests/baselines/reference/assignmentTypeNarrowing.js b/tests/baselines/reference/assignmentTypeNarrowing.js index 4d6b911b88b..24a08539eb7 100644 --- a/tests/baselines/reference/assignmentTypeNarrowing.js +++ b/tests/baselines/reference/assignmentTypeNarrowing.js @@ -27,6 +27,12 @@ let a: string[]; for (x of a) { x; // string } + +// Repro from #26405 + +type AOrArrA = T | T[]; +const arr: AOrArrA<{x?: "ok"}> = [{ x: "ok" }]; // weak type +arr.push({ x: "ok" }); //// [assignmentTypeNarrowing.js] @@ -51,3 +57,5 @@ for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { x = a_1[_i]; x; // string } +var arr = [{ x: "ok" }]; // weak type +arr.push({ x: "ok" }); diff --git a/tests/baselines/reference/assignmentTypeNarrowing.symbols b/tests/baselines/reference/assignmentTypeNarrowing.symbols index b9e8f3f136d..36a2cf44dae 100644 --- a/tests/baselines/reference/assignmentTypeNarrowing.symbols +++ b/tests/baselines/reference/assignmentTypeNarrowing.symbols @@ -62,3 +62,23 @@ for (x of a) { >x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 0, 3)) } +// Repro from #26405 + +type AOrArrA = T | T[]; +>AOrArrA : Symbol(AOrArrA, Decl(assignmentTypeNarrowing.ts, 27, 1)) +>T : Symbol(T, Decl(assignmentTypeNarrowing.ts, 31, 13)) +>T : Symbol(T, Decl(assignmentTypeNarrowing.ts, 31, 13)) +>T : Symbol(T, Decl(assignmentTypeNarrowing.ts, 31, 13)) + +const arr: AOrArrA<{x?: "ok"}> = [{ x: "ok" }]; // weak type +>arr : Symbol(arr, Decl(assignmentTypeNarrowing.ts, 32, 5)) +>AOrArrA : Symbol(AOrArrA, Decl(assignmentTypeNarrowing.ts, 27, 1)) +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 32, 20)) +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 32, 35)) + +arr.push({ x: "ok" }); +>arr.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>arr : Symbol(arr, Decl(assignmentTypeNarrowing.ts, 32, 5)) +>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(assignmentTypeNarrowing.ts, 33, 10)) + diff --git a/tests/baselines/reference/assignmentTypeNarrowing.types b/tests/baselines/reference/assignmentTypeNarrowing.types index 2e2e6ad44eb..15b71c259ae 100644 --- a/tests/baselines/reference/assignmentTypeNarrowing.types +++ b/tests/baselines/reference/assignmentTypeNarrowing.types @@ -96,3 +96,25 @@ for (x of a) { >x : string } +// Repro from #26405 + +type AOrArrA = T | T[]; +>AOrArrA : AOrArrA + +const arr: AOrArrA<{x?: "ok"}> = [{ x: "ok" }]; // weak type +>arr : AOrArrA<{ x?: "ok"; }> +>x : "ok" +>[{ x: "ok" }] : { x: "ok"; }[] +>{ x: "ok" } : { x: "ok"; } +>x : "ok" +>"ok" : "ok" + +arr.push({ x: "ok" }); +>arr.push({ x: "ok" }) : number +>arr.push : (...items: { x?: "ok"; }[]) => number +>arr : { x?: "ok"; }[] +>push : (...items: { x?: "ok"; }[]) => number +>{ x: "ok" } : { x: "ok"; } +>x : "ok" +>"ok" : "ok" + diff --git a/tests/baselines/reference/enumAssignmentCompat3.types b/tests/baselines/reference/enumAssignmentCompat3.types index f2a693515e5..a152cd624df 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.types +++ b/tests/baselines/reference/enumAssignmentCompat3.types @@ -252,9 +252,9 @@ abc = merged; // missing 'd' >merged : Merged.E merged = abc; // ok ->merged = abc : First.E.a | First.E.b +>merged = abc : First.E >merged : Merged.E ->abc : First.E.a | First.E.b +>abc : First.E abc = merged2; // ok >abc = merged2 : Merged2.E diff --git a/tests/baselines/reference/libReferenceDeclarationEmit.js b/tests/baselines/reference/libReferenceDeclarationEmit.js new file mode 100644 index 00000000000..83082c3ee98 --- /dev/null +++ b/tests/baselines/reference/libReferenceDeclarationEmit.js @@ -0,0 +1,25 @@ +//// [tests/cases/conformance/declarationEmit/libReferenceDeclarationEmit.ts] //// + +//// [file1.ts] +/// +export declare const elem: HTMLElement; + +//// [file2.ts] +/// +export {} +declare const elem: HTMLElement; + +//// [file1.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [file2.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + + +//// [file1.d.ts] +/// +export declare const elem: HTMLElement; +//// [file2.d.ts] +/// +export {}; diff --git a/tests/baselines/reference/libReferenceDeclarationEmit.symbols b/tests/baselines/reference/libReferenceDeclarationEmit.symbols new file mode 100644 index 00000000000..3753ee0b80d --- /dev/null +++ b/tests/baselines/reference/libReferenceDeclarationEmit.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/declarationEmit/file1.ts === +/// +export declare const elem: HTMLElement; +>elem : Symbol(elem, Decl(file1.ts, 1, 20)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +=== tests/cases/conformance/declarationEmit/file2.ts === +/// +export {} +declare const elem: HTMLElement; +>elem : Symbol(elem, Decl(file2.ts, 2, 13)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + diff --git a/tests/baselines/reference/libReferenceDeclarationEmit.types b/tests/baselines/reference/libReferenceDeclarationEmit.types new file mode 100644 index 00000000000..34102b07321 --- /dev/null +++ b/tests/baselines/reference/libReferenceDeclarationEmit.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/declarationEmit/file1.ts === +/// +export declare const elem: HTMLElement; +>elem : HTMLElement + +=== tests/cases/conformance/declarationEmit/file2.ts === +/// +export {} +declare const elem: HTMLElement; +>elem : HTMLElement + diff --git a/tests/baselines/reference/libReferenceDeclarationEmitBundle.js b/tests/baselines/reference/libReferenceDeclarationEmitBundle.js new file mode 100644 index 00000000000..03474372f87 --- /dev/null +++ b/tests/baselines/reference/libReferenceDeclarationEmitBundle.js @@ -0,0 +1,30 @@ +//// [tests/cases/conformance/declarationEmit/libReferenceDeclarationEmitBundle.ts] //// + +//// [file1.ts] +/// +export declare const elem: HTMLElement; + +//// [file2.ts] +/// +export {} +declare const elem: HTMLElement; + +//// [bundle.js] +define("file1", ["require", "exports"], function (require, exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); +}); +define("file2", ["require", "exports"], function (require, exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); +}); + + +//// [bundle.d.ts] +/// +declare module "file1" { + export const elem: HTMLElement; +} +declare module "file2" { + export {}; +} diff --git a/tests/baselines/reference/libReferenceDeclarationEmitBundle.symbols b/tests/baselines/reference/libReferenceDeclarationEmitBundle.symbols new file mode 100644 index 00000000000..3753ee0b80d --- /dev/null +++ b/tests/baselines/reference/libReferenceDeclarationEmitBundle.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/declarationEmit/file1.ts === +/// +export declare const elem: HTMLElement; +>elem : Symbol(elem, Decl(file1.ts, 1, 20)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + +=== tests/cases/conformance/declarationEmit/file2.ts === +/// +export {} +declare const elem: HTMLElement; +>elem : Symbol(elem, Decl(file2.ts, 2, 13)) +>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) + diff --git a/tests/baselines/reference/libReferenceDeclarationEmitBundle.types b/tests/baselines/reference/libReferenceDeclarationEmitBundle.types new file mode 100644 index 00000000000..34102b07321 --- /dev/null +++ b/tests/baselines/reference/libReferenceDeclarationEmitBundle.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/declarationEmit/file1.ts === +/// +export declare const elem: HTMLElement; +>elem : HTMLElement + +=== tests/cases/conformance/declarationEmit/file2.ts === +/// +export {} +declare const elem: HTMLElement; +>elem : HTMLElement + diff --git a/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.errors.txt b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.errors.txt new file mode 100644 index 00000000000..3c131f4136f --- /dev/null +++ b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.errors.txt @@ -0,0 +1,21 @@ +tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts(2,1): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts(5,1): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts(8,1): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + + +==== tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts (3 errors) ==== + function fnNumber(this: void): number { return 90; } + new fnNumber(); // Error + ~~~~~~~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + + function fnVoid(this: void): void {} + new fnVoid(); // Error + ~~~~~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + + function functionVoidNoThis(): void {} + new functionVoidNoThis(); // Error + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + \ No newline at end of file diff --git a/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.js b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.js new file mode 100644 index 00000000000..935c2ba036f --- /dev/null +++ b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.js @@ -0,0 +1,18 @@ +//// [newOperatorErrorCases_noImplicitAny.ts] +function fnNumber(this: void): number { return 90; } +new fnNumber(); // Error + +function fnVoid(this: void): void {} +new fnVoid(); // Error + +function functionVoidNoThis(): void {} +new functionVoidNoThis(); // Error + + +//// [newOperatorErrorCases_noImplicitAny.js] +function fnNumber() { return 90; } +new fnNumber(); // Error +function fnVoid() { } +new fnVoid(); // Error +function functionVoidNoThis() { } +new functionVoidNoThis(); // Error diff --git a/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.symbols b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.symbols new file mode 100644 index 00000000000..dadb2379223 --- /dev/null +++ b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts === +function fnNumber(this: void): number { return 90; } +>fnNumber : Symbol(fnNumber, Decl(newOperatorErrorCases_noImplicitAny.ts, 0, 0)) +>this : Symbol(this, Decl(newOperatorErrorCases_noImplicitAny.ts, 0, 18)) + +new fnNumber(); // Error +>fnNumber : Symbol(fnNumber, Decl(newOperatorErrorCases_noImplicitAny.ts, 0, 0)) + +function fnVoid(this: void): void {} +>fnVoid : Symbol(fnVoid, Decl(newOperatorErrorCases_noImplicitAny.ts, 1, 15)) +>this : Symbol(this, Decl(newOperatorErrorCases_noImplicitAny.ts, 3, 16)) + +new fnVoid(); // Error +>fnVoid : Symbol(fnVoid, Decl(newOperatorErrorCases_noImplicitAny.ts, 1, 15)) + +function functionVoidNoThis(): void {} +>functionVoidNoThis : Symbol(functionVoidNoThis, Decl(newOperatorErrorCases_noImplicitAny.ts, 4, 13)) + +new functionVoidNoThis(); // Error +>functionVoidNoThis : Symbol(functionVoidNoThis, Decl(newOperatorErrorCases_noImplicitAny.ts, 4, 13)) + diff --git a/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.types b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.types new file mode 100644 index 00000000000..bd1d8082aae --- /dev/null +++ b/tests/baselines/reference/newOperatorErrorCases_noImplicitAny.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts === +function fnNumber(this: void): number { return 90; } +>fnNumber : (this: void) => number +>this : void +>90 : 90 + +new fnNumber(); // Error +>new fnNumber() : any +>fnNumber : (this: void) => number + +function fnVoid(this: void): void {} +>fnVoid : (this: void) => void +>this : void + +new fnVoid(); // Error +>new fnVoid() : any +>fnVoid : (this: void) => void + +function functionVoidNoThis(): void {} +>functionVoidNoThis : () => void + +new functionVoidNoThis(); // Error +>new functionVoidNoThis() : any +>functionVoidNoThis : () => void + diff --git a/tests/baselines/reference/numericLiteralTypes3.types b/tests/baselines/reference/numericLiteralTypes3.types index 3fede24475c..9748eaccfca 100644 --- a/tests/baselines/reference/numericLiteralTypes3.types +++ b/tests/baselines/reference/numericLiteralTypes3.types @@ -118,9 +118,9 @@ function f4(a: A, b: B, c: C, d: D) { >c : C d = d; ->d = d : 1 | 2 +>d = d : D +>d : D >d : D ->d : 1 | 2 } function f5(a: A, b: B, c: C, d: D) { diff --git a/tests/cases/conformance/declarationEmit/libReferenceDeclarationEmit.ts b/tests/cases/conformance/declarationEmit/libReferenceDeclarationEmit.ts new file mode 100644 index 00000000000..2afc4290776 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/libReferenceDeclarationEmit.ts @@ -0,0 +1,12 @@ +// @target: esnext +// @module: commonjs +// @lib: esnext +// @declaration: true +// @filename: file1.ts +/// +export declare const elem: HTMLElement; + +// @filename: file2.ts +/// +export {} +declare const elem: HTMLElement; \ No newline at end of file diff --git a/tests/cases/conformance/declarationEmit/libReferenceDeclarationEmitBundle.ts b/tests/cases/conformance/declarationEmit/libReferenceDeclarationEmitBundle.ts new file mode 100644 index 00000000000..e379567d559 --- /dev/null +++ b/tests/cases/conformance/declarationEmit/libReferenceDeclarationEmitBundle.ts @@ -0,0 +1,13 @@ +// @target: esnext +// @module: amd +// @lib: esnext +// @declaration: true +// @outFile: bundle.js +// @filename: file1.ts +/// +export declare const elem: HTMLElement; + +// @filename: file2.ts +/// +export {} +declare const elem: HTMLElement; \ No newline at end of file diff --git a/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts b/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts index 0e5e257635a..19d12a1b81a 100644 --- a/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts +++ b/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts @@ -26,3 +26,9 @@ let a: string[]; for (x of a) { x; // string } + +// Repro from #26405 + +type AOrArrA = T | T[]; +const arr: AOrArrA<{x?: "ok"}> = [{ x: "ok" }]; // weak type +arr.push({ x: "ok" }); diff --git a/tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts b/tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts new file mode 100644 index 00000000000..9b3b2c091d6 --- /dev/null +++ b/tests/cases/conformance/expressions/newOperator/newOperatorErrorCases_noImplicitAny.ts @@ -0,0 +1,10 @@ +// @noImplicitAny: true + +function fnNumber(this: void): number { return 90; } +new fnNumber(); // Error + +function fnVoid(this: void): void {} +new fnVoid(); // Error + +function functionVoidNoThis(): void {} +new functionVoidNoThis(); // Error