Merge branch 'master' into release-2.4

This commit is contained in:
Mohamed Hegazy
2017-06-12 17:44:50 -07:00
162 changed files with 5741 additions and 973 deletions
+20 -1
View File
@@ -248,4 +248,23 @@ rdosanjh <me@rajdeep.io> # Raj Dosanjh
gdh1995 <gdh1995@qq.com> # Dahan Gong
cedvdb <cedvandenbosch@gmail.com> # @cedvdb
kpreisser <kpreisser@users.noreply.github.com> # K. Preißer
e-cloud <saintscott119@gmail.com> # @e-cloud
e-cloud <saintscott119@gmail.com> # @e-cloud
Andrew Casey <amcasey@users.noreply.github.com> Andrew Casey <andrew.casey@microsoft.com>
Andrew Stegmaier <andrew.stegmaier@gmail.com>
Benny Neugebauer <bn@bennyn.de>
Blaine Bublitz <blaine.bublitz@gmail.com>
Charles Pierce <cpierce.grad@gmail.com>
Daniel Król <daniel@krol.me>
Diogo Franco (Kovensky) <diogomfranco@gmail.com>
Donald Pipowitch <pipo@senaeh.de>
Halasi Tamás <trusted.tomato@gmail.com>
Ika <ikatyang@gmail.com>
Joe Chung <joechung@microsoft.com>
Kate Miháliková <kate@katemihalikova.cz>
Mohsen Azimi <mazimi@lyft.com>
Noel Varanda <ncwvaranda@gmail.com>
Reiner Dolp <reiner-dolp@users.noreply.github.com>
t_ <t-mrt@users.noreply.github.com> # @t_
TravCav <xurrux@gmail.com> # @TravCav
Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
William Orr <will@worrbase.com>
+19
View File
@@ -15,7 +15,9 @@ TypeScript is authored by:
* Anders Hejlsberg
* Andreas Martin
* Andrej Baran
* Andrew Casey
* Andrew Ochsner
* Andrew Stegmaier
* Andrew Z Allen
* András Parditka
* Andy Hanson
@@ -31,7 +33,9 @@ TypeScript is authored by:
* Ben Duffield
* Ben Mosher
* Benjamin Bock
* Benny Neugebauer
* Bill Ticehurst
* Blaine Bublitz
* Blake Embrey
* @bootstraponline
* Bowden Kelly
@@ -39,6 +43,7 @@ TypeScript is authored by:
* Bryan Forbes
* Caitlin Potter
* @cedvdb
* Charles Pierce
* Charly POLY
* Chris Bubernak
* Christophe Vidal
@@ -52,6 +57,7 @@ TypeScript is authored by:
* Dan Corder
* Dan Quirk
* Daniel Hollocher
* Daniel Król
* Daniel Lehenbauer
* Daniel Rosenwasser
* David Kmenta
@@ -60,9 +66,11 @@ TypeScript is authored by:
* David Souther
* Denis Nedelyaev
* Dick van den Brink
* Diogo Franco (Kovensky)
* Dirk Bäumer
* Dirk Holtwick
* Dom Chen
* Donald Pipowitch
* Doug Ilijev
* @e-cloud
* Elisée Maurer
@@ -89,12 +97,14 @@ TypeScript is authored by:
* Guilherme Oenning
* Guillaume Salles
* Guy Bedford
* Halasi Tamás
* Harald Niesche
* Hendrik Liebau
* Herrington Darkholme
* Homa Wong
* Iain Monro
* Igor Novozhilov
* Ika
* Ingvar Stepanyan
* Isiah Meadows
* Ivo Gabe de Wolff
@@ -111,6 +121,7 @@ TypeScript is authored by:
* Jeffrey Morlan
* Jesse Schalken
* Jiri Tobisek
* Joe Chung
* Joel Day
* Joey Wilson
* Johannes Rieken
@@ -131,6 +142,7 @@ TypeScript is authored by:
* K. Preißer
* Kagami Sascha Rosylight
* Kanchalai Tanglertsampan
* Kate Miháliková
* Keith Mashinter
* Ken Howard
* Kenji Imamula
@@ -159,6 +171,7 @@ TypeScript is authored by:
* Mike Busyrev
* Mine Starks
* Mohamed Hegazy
* Mohsen Azimi
* Myles Megyesi
* Natalie Coley
* Nathan Shively-Sanders
@@ -166,6 +179,7 @@ TypeScript is authored by:
* Nicolas Henry
* Nima Zahedi
* Noah Chen
* Noel Varanda
* Noj Vek
* Oleg Mihailik
* Oleksandr Chekhovskyi
@@ -186,6 +200,7 @@ TypeScript is authored by:
* Punya Biswal
* Rado Kirov
* Raj Dosanjh
* Reiner Dolp
* Richard Karmazín
* Richard Knoll
* Richard Sentino
@@ -213,6 +228,7 @@ TypeScript is authored by:
* Sudheesh Singanamalla
* Sébastien Arod
* @T18970237136
* @t_
* Tarik Ozket
* Tetsuharu Ohzeki
* Thomas Loubiou
@@ -225,13 +241,16 @@ TypeScript is authored by:
* togru
* Tomas Grubliauskas
* Torben Fitschen
* @TravCav
* TruongSinh Tran-Nguyen
* Vadi Taslim
* Vidar Tonaas Fauske
* Viktor Zozulyak
* Vilic Vane
* Vladimir Kurchatkin
* Vladimir Matveev
* Wesley Wigham
* William Orr
* York Yao
* @yortus
* Yuichi Nukiyama
+20 -17
View File
@@ -39,25 +39,25 @@ Error.stackTraceLimit = 1000;
const cmdLineOptions = minimist(process.argv.slice(2), {
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"],
alias: {
b: "browser",
d: "debug",
t: "tests",
test: "tests",
d: "debug", "debug-brk": "debug",
i: "inspect", "inspect-brk": "inspect",
t: "tests", test: "tests",
r: "reporter",
color: "colors",
f: "files",
file: "files",
c: "colors", color: "colors",
f: "files", file: "files",
w: "workers",
},
default: {
soft: false,
colors: process.env.colors || process.env.color || true,
debug: process.env.debug || process.env.d,
inspect: process.env.inspect,
debug: process.env.debug || process.env["debug-brk"] || process.env.d,
inspect: process.env.inspect || process.env["inspect-brk"] || process.env.i,
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
browser: process.env.browser || process.env.b || "IE",
timeout: process.env.timeout || 40000,
tests: process.env.test || process.env.tests || process.env.t,
light: process.env.light || false,
reporter: process.env.reporter || process.env.r,
@@ -594,11 +594,11 @@ function restoreSavedNodeEnv() {
process.env.NODE_ENV = savedNodeEnv;
}
let testTimeout = 40000;
function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) {
const lintFlag = cmdLineOptions["lint"];
cleanTestDirs((err) => {
if (err) { console.error(err); failWithStatus(err, 1); }
let testTimeout = cmdLineOptions["timeout"];
const debug = cmdLineOptions["debug"];
const inspect = cmdLineOptions["inspect"];
const tests = cmdLineOptions["tests"];
@@ -637,12 +637,6 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
if (!runInParallel) {
const args = [];
if (inspect) {
args.push("--inspect");
}
if (inspect || debug) {
args.push("--debug-brk");
}
args.push("-R", reporter);
if (tests) {
args.push("-g", `"${tests}"`);
@@ -653,7 +647,15 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
else {
args.push("--no-colors");
}
args.push("-t", testTimeout);
if (inspect) {
args.unshift("--inspect-brk");
}
else if (debug) {
args.unshift("--debug-brk");
}
else {
args.push("-t", testTimeout);
}
args.push(run);
setNodeEnvToDevelopment();
exec(mocha, args, lintThenFinish, function(e, status) {
@@ -838,6 +840,7 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like '
});
gulp.task("generate-code-coverage", "Generates code coverage data via istanbul", ["tests"], (done) => {
const testTimeout = cmdLineOptions["timeout"];
exec("istanbul", ["cover", "node_modules/mocha/bin/_mocha", "--", "-R", "min", "-t", testTimeout.toString(), run], done, done);
});
+20 -11
View File
@@ -25,6 +25,8 @@ var LKGDirectory = "lib/";
var copyright = "CopyrightNotice.txt";
var thirdParty = "ThirdPartyNoticeText.txt";
var defaultTestTimeout = 40000;
// add node_modules to path so we don't need global modules, prefer the modules by adding them first
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
if (process.env.path !== undefined) {
@@ -74,6 +76,10 @@ function measure(marker) {
console.log("travis_time:end:" + marker.id + ":start=" + toNs(marker.stamp) + ",finish=" + toNs(total) + ",duration=" + toNs(diff) + "\r");
}
function removeConstModifierFromEnumDeclarations(text) {
return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
}
var compilerSources = filesFromConfig("./src/compiler/tsconfig.json");
var servicesSources = filesFromConfig("./src/services/tsconfig.json");
var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json"));
@@ -551,7 +557,7 @@ compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].conc
// Stanalone/web definition file using global 'ts' namespace
jake.cpR(standaloneDefinitionsFile, nodeDefinitionsFile, { silent: true });
var definitionFileContents = fs.readFileSync(nodeDefinitionsFile).toString();
definitionFileContents = definitionFileContents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
definitionFileContents = removeConstModifierFromEnumDeclarations(definitionFileContents)
fs.writeFileSync(standaloneDefinitionsFile, definitionFileContents);
// Official node package definition file, pointed to by 'typings' in package.json
@@ -611,6 +617,7 @@ compileFile(
fs.readFileSync(tsserverLibraryDefinitionFile).toString() +
"\r\nexport = ts;" +
"\r\nexport as namespace ts;";
tsserverLibraryDefinitionFileContents = removeConstModifierFromEnumDeclarations(tsserverLibraryDefinitionFileContents);
fs.writeFileSync(tsserverLibraryDefinitionFile, tsserverLibraryDefinitionFileContents);
});
@@ -800,8 +807,8 @@ function runConsoleTests(defaultReporter, runInParallel) {
cleanTestDirs();
}
var debug = process.env.debug || process.env.d;
var inspect = process.env.inspect;
var debug = process.env.debug || process.env["debug-brk"] || process.env.d;
var inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i;
var testTimeout = process.env.timeout || defaultTestTimeout;
var tests = process.env.test || process.env.tests || process.env.t;
var light = process.env.light || false;
@@ -842,12 +849,6 @@ function runConsoleTests(defaultReporter, runInParallel) {
if (!runInParallel) {
var startTime = mark();
var args = [];
if (inspect) {
args.push("--inspect");
}
if (inspect || debug) {
args.push("--debug-brk");
}
args.push("-R", reporter);
if (tests) {
args.push("-g", `"${tests}"`);
@@ -861,7 +862,15 @@ function runConsoleTests(defaultReporter, runInParallel) {
if (bail) {
args.push("--bail");
}
args.push("-t", testTimeout);
if (inspect) {
args.unshift("--inspect-brk");
}
else if (debug) {
args.unshift("--debug-brk");
}
else {
args.push("-t", testTimeout);
}
args.push(run);
var cmd = "mocha " + args.join(" ");
@@ -926,7 +935,6 @@ function runConsoleTests(defaultReporter, runInParallel) {
}
}
var defaultTestTimeout = 22000;
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function () {
runConsoleTests('min', /*runInParallel*/ true);
@@ -939,6 +947,7 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() {
desc("Generates code coverage data via instanbul");
task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
var testTimeout = process.env.timeout || defaultTestTimeout;
var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run;
console.log(cmd);
exec(cmd);
+12 -7
View File
@@ -612,7 +612,7 @@ namespace ts {
break;
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
bindForInOrForOfStatement(<ForInStatement | ForOfStatement>node);
bindForInOrForOfStatement(<ForInOrOfStatement>node);
break;
case SyntaxKind.IfStatement:
bindIfStatement(<IfStatement>node);
@@ -950,7 +950,7 @@ namespace ts {
currentFlow = finishFlowLabel(postLoopLabel);
}
function bindForInOrForOfStatement(node: ForInStatement | ForOfStatement): void {
function bindForInOrForOfStatement(node: ForInOrOfStatement): void {
const preLoopLabel = createLoopLabel();
const postLoopLabel = createBranchLabel();
addAntecedent(preLoopLabel, currentFlow);
@@ -1328,7 +1328,7 @@ namespace ts {
function bindVariableDeclarationFlow(node: VariableDeclaration) {
bindEachChild(node);
if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) {
if (node.initializer || isForInOrOfStatement(node.parent.parent)) {
bindInitializedVariableFlow(node);
}
}
@@ -1521,7 +1521,7 @@ namespace ts {
// All the children of these container types are never visible through another
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
// they're only accessed 'lexically' (i.e. from code that exists underneath
// their container in the tree. To accomplish this, we simply add their declared
// their container in the tree). To accomplish this, we simply add their declared
// symbol to the 'locals' of the container. These symbols can then be found as
// the type checker walks up the containers, checking them for matching names.
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
@@ -2053,7 +2053,10 @@ namespace ts {
case SyntaxKind.TypePredicate:
return checkTypePredicate(node as TypePredicateNode);
case SyntaxKind.TypeParameter:
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
if (node.parent.kind !== ts.SyntaxKind.JSDocTemplateTag || isInJavaScriptFile(node)) {
return declareSymbolAndAddToSymbolTable(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes);
}
return;
case SyntaxKind.Parameter:
return bindParameter(<ParameterDeclaration>node);
case SyntaxKind.VariableDeclaration:
@@ -2135,8 +2138,10 @@ namespace ts {
case SyntaxKind.EnumDeclaration:
return bindEnumDeclaration(<EnumDeclaration>node);
case SyntaxKind.ModuleDeclaration:
return bindModuleDeclaration(<ModuleDeclaration>node);
if (node.parent.kind !== ts.SyntaxKind.JSDocTypedefTag || isInJavaScriptFile(node)) {
return bindModuleDeclaration(<ModuleDeclaration>node);
}
return undefined;
// Jsx-attributes
case SyntaxKind.JsxAttributes:
return bindJsxAttributes(<JsxAttributes>node);
+233 -234
View File
@@ -804,16 +804,8 @@ namespace ts {
break;
}
switch (declaration.parent.parent.kind) {
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
// ForIn/ForOf case - use site should not be used in expression part
if (isSameScopeDescendentOf(usage, (<ForInStatement | ForOfStatement>declaration.parent.parent).expression, container)) {
return true;
}
}
return false;
// ForIn/ForOf case - use site should not be used in expression part
return isForInOrOfStatement(declaration.parent.parent) && isSameScopeDescendentOf(usage, declaration.parent.parent.expression, container);
}
function isUsedInFunctionOrInstanceProperty(usage: Node, declaration: Node, container?: Node): boolean {
@@ -4200,16 +4192,6 @@ namespace ts {
// Return the inferred type for a variable, parameter, or property declaration
function getTypeForVariableLikeDeclaration(declaration: VariableLikeDeclaration, includeOptionality: boolean): Type {
if (declaration.flags & NodeFlags.JavaScriptFile) {
// If this is a variable in a JavaScript file, then use the JSDoc type (if it has
// one as its type), otherwise fallback to the below standard TS codepaths to
// try to figure it out.
const type = getTypeForDeclarationFromJSDocComment(declaration);
if (type && type !== unknownType) {
return type;
}
}
// A variable declared in a for..in statement is of type string, or of type keyof T when the
// right hand expression is of a type parameter type.
if (declaration.parent.parent.kind === SyntaxKind.ForInStatement) {
@@ -4231,8 +4213,9 @@ namespace ts {
}
// Use type from type annotation if one is present
if (declaration.type) {
const declaredType = getTypeFromTypeNode(declaration.type);
const typeNode = getEffectiveTypeAnnotationNode(declaration);
if (typeNode) {
const declaredType = getTypeFromTypeNode(typeNode);
return addOptionality(declaredType, /*optional*/ declaration.questionToken && includeOptionality);
}
@@ -4523,10 +4506,11 @@ namespace ts {
function getAnnotatedAccessorType(accessor: AccessorDeclaration): Type {
if (accessor) {
if (accessor.kind === SyntaxKind.GetAccessor) {
return accessor.type && getTypeFromTypeNode(accessor.type);
const getterTypeAnnotation = getEffectiveReturnTypeNode(accessor);
return getterTypeAnnotation && getTypeFromTypeNode(getterTypeAnnotation);
}
else {
const setterTypeAnnotation = getSetAccessorTypeAnnotationNode(accessor);
const setterTypeAnnotation = getEffectiveSetAccessorTypeAnnotationNode(accessor);
return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation);
}
}
@@ -4679,7 +4663,7 @@ namespace ts {
function reportCircularityError(symbol: Symbol) {
// Check if variable has type annotation that circularly references the variable itself
if ((<VariableLikeDeclaration>symbol.valueDeclaration).type) {
if (getEffectiveTypeAnnotationNode(<VariableLikeDeclaration>symbol.valueDeclaration)) {
error(symbol.valueDeclaration, Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation,
symbolToString(symbol));
return unknownType;
@@ -5265,14 +5249,18 @@ namespace ts {
// A variable-like declaration is considered independent (free of this references) if it has a type annotation
// that specifies an independent type, or if it has no type annotation and no initializer (and thus of type any).
function isIndependentVariableLikeDeclaration(node: VariableLikeDeclaration): boolean {
return node.type && isIndependentType(node.type) || !node.type && !node.initializer;
const typeNode = getEffectiveTypeAnnotationNode(node);
return typeNode ? isIndependentType(typeNode) : !node.initializer;
}
// A function-like declaration is considered independent (free of this references) if it has a return type
// annotation that is considered independent and if each parameter is considered independent.
function isIndependentFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
if (node.kind !== SyntaxKind.Constructor && (!node.type || !isIndependentType(node.type))) {
return false;
if (node.kind !== SyntaxKind.Constructor) {
const typeNode = getEffectiveReturnTypeNode(node);
if (!typeNode || !isIndependentType(typeNode)) {
return false;
}
}
for (const parameter of node.parameters) {
if (!isIndependentVariableLikeDeclaration(parameter)) {
@@ -5985,7 +5973,7 @@ namespace ts {
typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType;
}
else {
const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameter(decl) && decl.default);
const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameterDeclaration(decl) && decl.default);
typeParameter.default = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType;
}
}
@@ -6182,24 +6170,16 @@ namespace ts {
return undefined;
}
function getTypeParametersFromJSDocTemplate(declaration: SignatureDeclaration): TypeParameter[] {
if (declaration.flags & NodeFlags.JavaScriptFile) {
const templateTag = getJSDocTemplateTag(declaration);
if (templateTag) {
return getTypeParametersFromDeclaration(templateTag.typeParameters);
}
}
return undefined;
}
// Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
// type checking functions).
function getTypeParametersFromDeclaration(typeParameterDeclarations: TypeParameterDeclaration[]): TypeParameter[] {
const result: TypeParameter[] = [];
forEach(typeParameterDeclarations, node => {
function getTypeParametersFromDeclaration(declaration: DeclarationWithTypeParameters): TypeParameter[] {
let result: TypeParameter[];
forEach(getEffectiveTypeParameterDeclarations(declaration), node => {
const tp = getDeclaredTypeOfTypeParameter(node.symbol);
if (!contains(result, tp)) {
if (!result) {
result = [];
}
result.push(tp);
}
});
@@ -6395,9 +6375,7 @@ namespace ts {
const classType = declaration.kind === SyntaxKind.Constructor ?
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
: undefined;
const typeParameters = classType ? classType.localTypeParameters :
declaration.typeParameters ? getTypeParametersFromDeclaration(declaration.typeParameters) :
getTypeParametersFromJSDocTemplate(declaration);
const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType);
const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
@@ -6424,15 +6402,10 @@ namespace ts {
else if (classType) {
return classType;
}
else if (declaration.type) {
return getTypeFromTypeNode(declaration.type);
}
if (declaration.flags & NodeFlags.JavaScriptFile) {
const type = getReturnTypeFromJSDocComment(declaration);
if (type && type !== unknownType) {
return type;
}
const typeNode = getEffectiveReturnTypeNode(declaration);
if (typeNode) {
return getTypeFromTypeNode(typeNode);
}
// TypeScript 1.0 spec (April 2014):
@@ -6841,21 +6814,46 @@ namespace ts {
return undefined;
}
function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName) {
function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName, meaning: SymbolFlags) {
if (!typeReferenceName) {
return unknownSymbol;
}
return resolveEntityName(typeReferenceName, SymbolFlags.Type) || unknownSymbol;
return resolveEntityName(typeReferenceName, meaning) || unknownSymbol;
}
function getTypeReferenceType(node: TypeReferenceType, symbol: Symbol) {
const typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced.
if (symbol === unknownSymbol) {
return unknownType;
}
const type = getTypeReferenceTypeWorker(node, symbol, typeArguments);
if (type) {
return type;
}
if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
// A JSDocTypeReference may have resolved to a value (as opposed to a type). If
// the symbol is a constructor function, return the inferred class type; otherwise,
// the type of this reference is just the type of the value we resolved to.
const valueType = getTypeOfSymbol(symbol);
if (valueType.symbol && !isInferredClassType(valueType)) {
const referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments);
if (referenceType) {
return referenceType;
}
}
// Resolve the type reference as a Type for the purpose of reporting errors.
resolveTypeReferenceName(getTypeReferenceName(node), SymbolFlags.Type);
return valueType;
}
return getTypeFromNonGenericTypeReference(node, symbol);
}
function getTypeReferenceTypeWorker(node: TypeReferenceType, symbol: Symbol, typeArguments: Type[]): Type | undefined {
if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments);
}
@@ -6864,14 +6862,9 @@ namespace ts {
return getTypeFromTypeAliasReference(node, symbol, typeArguments);
}
if (symbol.flags & SymbolFlags.Value && node.kind === SyntaxKind.JSDocTypeReference) {
// A JSDocTypeReference may have resolved to a value (as opposed to a type). In
// that case, the type of this reference is just the type of the value we resolved
// to.
return getTypeOfSymbol(symbol);
if (symbol.flags & SymbolFlags.Function && node.kind === SyntaxKind.JSDocTypeReference && (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) {
return getInferredClassType(symbol);
}
return getTypeFromNonGenericTypeReference(node, symbol);
}
function getPrimitiveTypeFromJSDocTypeReference(node: JSDocTypeReference): Type {
@@ -6914,22 +6907,13 @@ namespace ts {
if (!links.resolvedType) {
let symbol: Symbol;
let type: Type;
let meaning = SymbolFlags.Type;
if (node.kind === SyntaxKind.JSDocTypeReference) {
type = getPrimitiveTypeFromJSDocTypeReference(<JSDocTypeReference>node);
if (!type) {
const typeReferenceName = getTypeReferenceName(node);
symbol = resolveTypeReferenceName(typeReferenceName);
type = getTypeReferenceType(node, symbol);
}
type = getPrimitiveTypeFromJSDocTypeReference(node);
meaning |= SymbolFlags.Value;
}
else {
// We only support expressions that are simple qualified names. For other expressions this produces undefined.
const typeNameOrExpression: EntityNameOrEntityNameExpression = node.kind === SyntaxKind.TypeReference
? (<TypeReferenceNode>node).typeName
: isEntityNameExpression((<ExpressionWithTypeArguments>node).expression)
? <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression
: undefined;
symbol = typeNameOrExpression && resolveEntityName(typeNameOrExpression, SymbolFlags.Type) || unknownSymbol;
if (!type) {
symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
type = getTypeReferenceType(node, symbol);
}
// Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the
@@ -7166,6 +7150,7 @@ namespace ts {
containsAny?: boolean;
containsUndefined?: boolean;
containsNull?: boolean;
containsNever?: boolean;
containsNonWideningType?: boolean;
containsString?: boolean;
containsNumber?: boolean;
@@ -7367,10 +7352,13 @@ namespace ts {
else if (type.flags & TypeFlags.Any) {
typeSet.containsAny = true;
}
else if (type.flags & TypeFlags.Never) {
typeSet.containsNever = true;
}
else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) {
typeSet.containsEmptyObject = true;
}
else if (!(type.flags & TypeFlags.Never) && (strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
else if ((strictNullChecks || !(type.flags & TypeFlags.Nullable)) && !contains(typeSet, type)) {
if (type.flags & TypeFlags.Object) {
typeSet.containsObjectType = true;
}
@@ -7408,6 +7396,9 @@ namespace ts {
}
const typeSet = [] as TypeSet;
addTypesToIntersection(typeSet, types);
if (typeSet.containsNever) {
return neverType;
}
if (typeSet.containsAny) {
return anyType;
}
@@ -8058,7 +8049,7 @@ namespace ts {
const result = createSignature(signature.declaration, freshTypeParameters,
signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper),
instantiateList(signature.parameters, mapper, instantiateSymbol),
instantiateType(signature.resolvedReturnType, mapper),
/*resolvedReturnType*/ undefined,
freshTypePredicate,
signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
result.target = signature;
@@ -8165,9 +8156,9 @@ namespace ts {
case SyntaxKind.ClassExpression:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.TypeAliasDeclaration:
const declaration = node as DeclarationWithTypeParameters;
if (declaration.typeParameters) {
for (const d of declaration.typeParameters) {
const typeParameters = getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters);
if (typeParameters) {
for (const d of typeParameters) {
if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) {
return true;
}
@@ -8322,7 +8313,7 @@ namespace ts {
return false;
}
// Functions with any parameters that lack type annotations are context sensitive.
if (forEach(node.parameters, p => !p.type)) {
if (forEach(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
return true;
}
// For arrow functions we now know we're not context sensitive.
@@ -8449,10 +8440,9 @@ namespace ts {
return Ternary.False;
}
// Spec 1.0 Section 3.8.3 & 3.8.4:
// M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
source = getErasedSignature(source);
target = getErasedSignature(target);
if (source.typeParameters) {
source = instantiateSignatureInContextOf(source, target);
}
let result = Ternary.True;
@@ -8966,7 +8956,9 @@ namespace ts {
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target));
}
else {
errorNode = prop.valueDeclaration;
if (prop.valueDeclaration) {
errorNode = prop.valueDeclaration;
}
reportError(Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1,
symbolToString(prop), typeToString(target));
}
@@ -9488,23 +9480,33 @@ namespace ts {
const saveErrorInfo = errorInfo;
if (getObjectFlags(source) & ObjectFlags.Instantiated && getObjectFlags(target) & ObjectFlags.Instantiated && source.symbol === target.symbol) {
// We instantiations of the same anonymous type (which typically will be the type of a method).
// Simply do a pairwise comparison of the signatures in the two signature lists instead of the
// much more expensive N * M comparison matrix we explore below.
// We have instantiations of the same anonymous type (which typically will be the type of a
// method). Simply do a pairwise comparison of the signatures in the two signature lists instead
// of the much more expensive N * M comparison matrix we explore below. We erase type parameters
// as they are known to always be the same.
for (let i = 0; i < targetSignatures.length; i++) {
const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], reportErrors);
const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors);
if (!related) {
return Ternary.False;
}
result &= related;
}
}
else if (sourceSignatures.length === 1 && targetSignatures.length === 1) {
// For simple functions (functions with a single signature) we only erase type parameters for
// the comparable relation. Otherwise, if the source signature is generic, we instantiate it
// in the context of the target signature before checking the relationship. Ideally we'd do
// this regardless of the number of signatures, but the potential costs are prohibitive due
// to the quadratic nature of the logic below.
const eraseGenerics = relation === comparableRelation || compilerOptions.noStrictGenericChecks;
result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors);
}
else {
outer: for (const t of targetSignatures) {
// Only elaborate errors from the first failure
let shouldElaborateErrors = reportErrors;
for (const s of sourceSignatures) {
const related = signatureRelatedTo(s, t, shouldElaborateErrors);
const related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors);
if (related) {
result &= related;
errorInfo = saveErrorInfo;
@@ -9527,8 +9529,9 @@ namespace ts {
/**
* See signatureAssignableTo, compareSignaturesIdentical
*/
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
return compareSignaturesRelated(source, target, /*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean): Ternary {
return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
/*checkAsCallback*/ false, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
}
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
@@ -12741,8 +12744,15 @@ namespace ts {
function getContextualTypeForInitializerExpression(node: Expression): Type {
const declaration = <VariableLikeDeclaration>node.parent;
if (node === declaration.initializer) {
if (declaration.type) {
return getTypeFromTypeNode(declaration.type);
const typeNode = getEffectiveTypeAnnotationNode(declaration);
if (typeNode) {
return getTypeFromTypeNode(typeNode);
}
if (isInJavaScriptFile(declaration)) {
const jsDocType = getTypeForDeclarationFromJSDocComment(declaration);
if (jsDocType) {
return jsDocType;
}
}
if (declaration.kind === SyntaxKind.Parameter) {
const type = getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
@@ -12756,12 +12766,13 @@ namespace ts {
if (isBindingPattern(declaration.parent)) {
const parentDeclaration = declaration.parent.parent;
const name = declaration.propertyName || declaration.name;
if (parentDeclaration.kind !== SyntaxKind.BindingElement &&
parentDeclaration.type &&
!isBindingPattern(name)) {
const text = getTextOfPropertyName(name);
if (text) {
return getTypeOfPropertyOfType(getTypeFromTypeNode(parentDeclaration.type), text);
if (parentDeclaration.kind !== SyntaxKind.BindingElement) {
const parentTypeNode = getEffectiveTypeAnnotationNode(parentDeclaration);
if (parentTypeNode && !isBindingPattern(name)) {
const text = getTextOfPropertyName(name);
if (text) {
return getTypeOfPropertyOfType(getTypeFromTypeNode(parentTypeNode), text);
}
}
}
}
@@ -12815,9 +12826,9 @@ namespace ts {
function getContextualReturnType(functionDecl: FunctionLikeDeclaration): Type {
// If the containing function has a return type annotation, is a constructor, or is a get accessor whose
// corresponding set accessor has a type annotation, return statements in the function are contextually typed
if (functionDecl.type ||
functionDecl.kind === SyntaxKind.Constructor ||
functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(functionDecl.symbol, SyntaxKind.SetAccessor))) {
if (functionDecl.kind === SyntaxKind.Constructor ||
getEffectiveReturnTypeNode(functionDecl) ||
isGetAccessorWithAnnotatedSetAccessor(functionDecl)) {
return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
}
@@ -14214,9 +14225,13 @@ namespace ts {
/**
* Check if a property with the given name is known anywhere in the given type. In an object type, a property
* is considered known if the object type is empty and the check is for assignability, if the object type has
* index signatures, or if the property is actually declared in the object type. In a union or intersection
* type, a property is considered known if it is known in any constituent type.
* is considered known if
* 1. the object type is empty and the check is for assignability, or
* 2. if the object type has index signatures, or
* 3. if the property is actually declared in the object type
* (this means that 'toString', for example, is not usually a known property).
* 4. In a union or intersection type,
* a property is considered known if it is known in any constituent type.
* @param targetType a type to search a given name in
* @param name a property name to search
* @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType
@@ -14226,7 +14241,7 @@ namespace ts {
const resolved = resolveStructuredTypeMembers(<ObjectType>targetType);
if (resolved.stringIndexInfo ||
resolved.numberIndexInfo && isNumericLiteralName(name) ||
getPropertyOfType(targetType, name) ||
getPropertyOfObjectType(targetType, name) ||
isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
// For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
return true;
@@ -14964,12 +14979,15 @@ namespace ts {
}
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper: TypeMapper): Signature {
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper?: TypeMapper): Signature {
const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes);
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
inferTypes(context.inferences, instantiateType(source, contextualMapper), target);
inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target);
});
if (!contextualMapper) {
inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), InferencePriority.ReturnType);
}
return getSignatureInstantiation(signature, getInferredTypes(context));
}
@@ -15009,10 +15027,10 @@ namespace ts {
// outer call expression. Effectively we just want a snapshot of whatever has been
// inferred for any outer call expression so far.
const instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node)));
// If the contextual type is a generic pure function type, we instantiate the type with
// its own type parameters and type arguments. This ensures that the type parameters are
// not erased to type any during type inference such that they can be inferred as actual
// types from the contextual type. For example:
// If the contextual type is a generic function type with a single call signature, we
// instantiate the type with its own type parameters and type arguments. This ensures that
// the type parameters are not erased to type any during type inference such that they can
// be inferred as actual types from the contextual type. For example:
// declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
// const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
// Above, the type of the 'value' parameter is inferred to be 'A'.
@@ -16169,6 +16187,12 @@ namespace ts {
return links.inferredClassType;
}
function isInferredClassType(type: Type) {
return type.symbol
&& getObjectFlags(type) & ObjectFlags.Anonymous
&& getSymbolLinks(type.symbol).inferredClassType === type;
}
/**
* Syntactically and semantically checks a call or new expression.
* @param node The call/new expression to be checked.
@@ -16340,37 +16364,43 @@ namespace ts {
return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType;
}
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper, checkMode: CheckMode) {
function inferFromAnnotatedParameters(signature: Signature, context: Signature, mapper: TypeMapper) {
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
if (checkMode === CheckMode.Inferential) {
for (let i = 0; i < len; i++) {
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
if (declaration.type) {
inferTypes((<InferenceContext>mapper).inferences, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
for (let i = 0; i < len; i++) {
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
if (declaration.type) {
const typeNode = getEffectiveTypeAnnotationNode(declaration);
if (typeNode) {
inferTypes((<InferenceContext>mapper).inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
}
}
}
}
function assignContextualParameterTypes(signature: Signature, context: Signature) {
signature.typeParameters = context.typeParameters;
if (context.thisParameter) {
const parameter = signature.thisParameter;
if (!parameter || parameter.valueDeclaration && !(<ParameterDeclaration>parameter.valueDeclaration).type) {
if (!parameter) {
signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
}
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper, checkMode);
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter));
}
}
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
for (let i = 0; i < len; i++) {
const parameter = signature.parameters[i];
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
const contextualParameterType = getTypeAtPosition(context, i);
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode);
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
}
}
if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
const parameter = lastOrUndefined(signature.parameters);
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode);
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
}
}
}
@@ -16390,10 +16420,10 @@ namespace ts {
}
}
function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper, checkMode: CheckMode) {
function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type) {
const links = getSymbolLinks(parameter);
if (!links.type) {
links.type = instantiateType(contextualType, mapper);
links.type = contextualType;
const name = getNameOfDeclaration(parameter.valueDeclaration);
// if inference didn't come up with anything but {}, fall back to the binding pattern if present.
if (links.type === emptyObjectType &&
@@ -16402,47 +16432,6 @@ namespace ts {
}
assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
}
else if (checkMode === CheckMode.Inferential) {
// Even if the parameter already has a type, it might be because it was given a type while
// processing the function as an argument to a prior signature during overload resolution.
// If this was the case, it may have caused some type parameters to be fixed. So here,
// we need to ensure that type parameters at the same positions get fixed again. This is
// done by calling instantiateType to attach the mapper to the contextualType, and then
// calling inferTypes to force a walk of contextualType so that all the correct fixing
// happens. The choice to pass in links.type may seem kind of arbitrary, but it serves
// to make sure that all the correct positions in contextualType are reached by the walk.
// Here is an example:
//
// interface Base {
// baseProp;
// }
// interface Derived extends Base {
// toBase(): Base;
// }
//
// var derived: Derived;
//
// declare function foo<T>(x: T, func: (p: T) => T): T;
// declare function foo<T>(x: T, func: (p: T) => T): T;
//
// var result = foo(derived, d => d.toBase());
//
// We are typing d while checking the second overload. But we've already given d
// a type (Derived) from the first overload. However, we still want to fix the
// T in the second overload so that we do not infer Base as a candidate for T
// (inferring Base would make type argument inference inconsistent between the two
// overloads).
inferTypes((<InferenceContext>mapper).inferences, links.type, instantiateType(contextualType, mapper));
}
}
function getReturnTypeFromJSDocComment(func: SignatureDeclaration | FunctionDeclaration): Type {
const returnTag = getJSDocReturnTag(func);
if (returnTag && returnTag.typeExpression) {
return getTypeFromTypeNode(returnTag.typeExpression.type);
}
return undefined;
}
function createPromiseType(promisedType: Type): Type {
@@ -16670,16 +16659,16 @@ namespace ts {
const hasExplicitReturn = func.flags & NodeFlags.HasExplicitReturn;
if (returnType && returnType.flags & TypeFlags.Never) {
error(func.type, Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
}
else if (returnType && !hasExplicitReturn) {
// minimal check: function has syntactic return type annotation and no explicit return statements in the body
// this function does not conform to the specification.
// NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
error(func.type, Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
error(getEffectiveReturnTypeNode(func), Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
}
else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) {
error(func.type, Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
error(getEffectiveReturnTypeNode(func), Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
}
else if (compilerOptions.noImplicitReturns) {
if (!returnType) {
@@ -16694,7 +16683,7 @@ namespace ts {
return;
}
}
error(func.type || func, Diagnostics.Not_all_code_paths_return_a_value);
error(getEffectiveReturnTypeNode(func) || func, Diagnostics.Not_all_code_paths_return_a_value);
}
}
@@ -16715,37 +16704,35 @@ namespace ts {
const links = getNodeLinks(node);
const type = getTypeOfSymbol(node.symbol);
const contextSensitive = isContextSensitive(node);
const mightFixTypeParameters = contextSensitive && checkMode === CheckMode.Inferential;
// Check if function expression is contextually typed and assign parameter types if so.
// See the comment in assignTypeToParameterAndFixTypeParameters to understand why we need to
// check mightFixTypeParameters.
if (mightFixTypeParameters || !(links.flags & NodeCheckFlags.ContextChecked)) {
if (!(links.flags & NodeCheckFlags.ContextChecked)) {
const contextualSignature = getContextualSignature(node);
// If a type check is started at a function expression that is an argument of a function call, obtaining the
// contextual type may recursively get back to here during overload resolution of the call. If so, we will have
// already assigned contextual types.
const contextChecked = !!(links.flags & NodeCheckFlags.ContextChecked);
if (mightFixTypeParameters || !contextChecked) {
if (!(links.flags & NodeCheckFlags.ContextChecked)) {
links.flags |= NodeCheckFlags.ContextChecked;
if (contextualSignature) {
const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
if (contextSensitive) {
assignContextualParameterTypes(signature, contextualSignature, getContextualMapper(node), checkMode);
if (isContextSensitive(node)) {
const contextualMapper = getContextualMapper(node);
if (checkMode === CheckMode.Inferential) {
inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
}
const instantiatedContextualSignature = contextualMapper === identityMapper ?
contextualSignature : instantiateSignature(contextualSignature, contextualMapper);
assignContextualParameterTypes(signature, instantiatedContextualSignature);
}
if (mightFixTypeParameters || !node.type && !signature.resolvedReturnType) {
if (!getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) {
const returnType = getReturnTypeFromBody(node, checkMode);
if (!signature.resolvedReturnType) {
signature.resolvedReturnType = returnType;
}
}
}
if (!contextChecked) {
checkSignatureDeclaration(node);
checkNodeDeferred(node);
}
checkSignatureDeclaration(node);
checkNodeDeferred(node);
}
}
@@ -16762,10 +16749,11 @@ namespace ts {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
const functionFlags = getFunctionFlags(node);
const returnOrPromisedType = node.type &&
const returnTypeNode = getEffectiveReturnTypeNode(node);
const returnOrPromisedType = returnTypeNode &&
((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ?
checkAsyncFunctionReturnType(node) : // Async function
getTypeFromTypeNode(node.type)); // AsyncGenerator function, Generator function, or normal function
getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function
if ((functionFlags & FunctionFlags.Generator) === 0) { // Async function or normal function
// return is not necessary in the body of generators
@@ -16773,7 +16761,7 @@ namespace ts {
}
if (node.body) {
if (!node.type) {
if (!returnTypeNode) {
// There are some checks that are only performed in getReturnTypeFromBody, that may produce errors
// we need. An example is the noImplicitAny errors resulting from widening the return expression
// of a function. Because checking of function expression bodies is deferred, there was never an
@@ -16865,7 +16853,7 @@ namespace ts {
function checkReferenceExpression(expr: Expression, invalidReferenceMessage: DiagnosticMessage): boolean {
// References are combinations of identifiers, parentheses, and property accesses.
const node = skipParentheses(expr);
const node = skipOuterExpressions(expr, OuterExpressionKinds.Assertions | OuterExpressionKinds.Parentheses);
if (node.kind !== SyntaxKind.Identifier && node.kind !== SyntaxKind.PropertyAccessExpression && node.kind !== SyntaxKind.ElementAccessExpression) {
error(expr, invalidReferenceMessage);
return false;
@@ -17559,8 +17547,9 @@ namespace ts {
// There is no point in doing an assignability check if the function
// has no explicit return type because the return type is directly computed
// from the yield expressions.
if (func.type) {
const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(func.type), (functionFlags & FunctionFlags.Async) !== 0) || anyType;
const returnType = getEffectiveReturnTypeNode(func);
if (returnType) {
const signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & FunctionFlags.Async) !== 0) || anyType;
if (nodeIsYieldStar) {
checkTypeAssignableTo(
functionFlags & FunctionFlags.Async
@@ -17716,7 +17705,7 @@ namespace ts {
if (signature && signature.typeParameters) {
const contextualType = getApparentTypeOfContextualType(<Expression>node);
if (contextualType) {
const contextualSignature = getSingleCallSignature(contextualType);
const contextualSignature = getSingleCallSignature(getNonNullableType(contextualType));
if (contextualSignature && !contextualSignature.typeParameters) {
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
}
@@ -18088,13 +18077,15 @@ namespace ts {
forEach(node.parameters, checkParameter);
// TODO(rbuckton): Should we start checking JSDoc types?
if (node.type) {
checkSourceElement(node.type);
}
if (produceDiagnostics) {
checkCollisionWithArgumentsInGeneratedCode(node);
if (noImplicitAny && !node.type) {
const returnTypeNode = getEffectiveReturnTypeNode(node);
if (noImplicitAny && !returnTypeNode) {
switch (node.kind) {
case SyntaxKind.ConstructSignature:
error(node, Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
@@ -18105,12 +18096,12 @@ namespace ts {
}
}
if (node.type) {
if (returnTypeNode) {
const functionFlags = getFunctionFlags(<FunctionDeclaration>node);
if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Generator)) === FunctionFlags.Generator) {
const returnType = getTypeFromTypeNode(node.type);
const returnType = getTypeFromTypeNode(returnTypeNode);
if (returnType === voidType) {
error(node.type, Diagnostics.A_generator_cannot_have_a_void_type_annotation);
error(returnTypeNode, Diagnostics.A_generator_cannot_have_a_void_type_annotation);
}
else {
const generatorElementType = getIteratedTypeOfGenerator(returnType, (functionFlags & FunctionFlags.Async) !== 0) || anyType;
@@ -18124,7 +18115,7 @@ namespace ts {
// interface BadGenerator extends Iterable<number>, Iterator<string> { }
// function* g(): BadGenerator { } // Iterable and Iterator have different types!
//
checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type);
checkTypeAssignableTo(iterableIteratorInstantiation, returnType, returnTypeNode);
}
}
else if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) {
@@ -19136,7 +19127,8 @@ namespace ts {
// then<U>(...): Promise<U>;
// }
//
const returnType = getTypeFromTypeNode(node.type);
const returnTypeNode = getEffectiveReturnTypeNode(node);
const returnType = getTypeFromTypeNode(returnTypeNode);
if (languageVersion >= ScriptTarget.ES2015) {
if (returnType === unknownType) {
@@ -19146,21 +19138,21 @@ namespace ts {
if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
// The promise type was not a valid type reference to the global promise type, so we
// report an error and return the unknown type.
error(node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
error(returnTypeNode, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
return unknownType;
}
}
else {
// Always mark the type node as referenced if it points to a value
markTypeNodeAsReferenced(node.type);
markTypeNodeAsReferenced(returnTypeNode);
if (returnType === unknownType) {
return unknownType;
}
const promiseConstructorName = getEntityNameFromTypeNode(node.type);
const promiseConstructorName = getEntityNameFromTypeNode(returnTypeNode);
if (promiseConstructorName === undefined) {
error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
return unknownType;
}
@@ -19168,10 +19160,10 @@ namespace ts {
const promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType;
if (promiseConstructorType === unknownType) {
if (promiseConstructorName.kind === SyntaxKind.Identifier && promiseConstructorName.text === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) {
error(node.type, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
error(returnTypeNode, Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
}
else {
error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
}
return unknownType;
}
@@ -19180,11 +19172,11 @@ namespace ts {
if (globalPromiseConstructorLikeType === emptyObjectType) {
// If we couldn't resolve the global PromiseConstructorLike type we cannot verify
// compatibility with __awaiter.
error(node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
error(returnTypeNode, Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, entityNameToString(promiseConstructorName));
return unknownType;
}
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type,
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode,
Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
return unknownType;
}
@@ -19329,7 +19321,8 @@ namespace ts {
}
function getParameterTypeNodeForDecoratorCheck(node: ParameterDeclaration): TypeNode {
return node.dotDotDotToken ? getRestParameterElementType(node.type) : node.type;
const typeNode = getEffectiveTypeAnnotationNode(node);
return isRestParameter(node) ? getRestParameterElementType(typeNode) : typeNode;
}
/** Check the decorators of a node */
@@ -19375,14 +19368,15 @@ namespace ts {
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
}
markDecoratorMedataDataTypeNodeAsReferenced((<FunctionLikeDeclaration>node).type);
markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(<FunctionLikeDeclaration>node));
break;
case SyntaxKind.PropertyDeclaration:
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(<ParameterDeclaration>node));
markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveTypeAnnotationNode(<ParameterDeclaration>node));
break;
case SyntaxKind.Parameter:
markDecoratorMedataDataTypeNodeAsReferenced((<PropertyDeclaration>node).type);
markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(<ParameterDeclaration>node));
break;
}
}
@@ -19392,8 +19386,8 @@ namespace ts {
function checkFunctionDeclaration(node: FunctionDeclaration): void {
if (produceDiagnostics) {
checkFunctionOrMethodDeclaration(node) || checkGrammarForGenerator(node);
checkFunctionOrMethodDeclaration(node);
checkGrammarForGenerator(node);
checkCollisionWithCapturedSuperVariable(node, node.name);
checkCollisionWithCapturedThisVariable(node, node.name);
checkCollisionWithCapturedNewTargetVariable(node, node.name);
@@ -19447,14 +19441,15 @@ namespace ts {
checkSourceElement(node.body);
const returnTypeNode = getEffectiveReturnTypeNode(node);
if ((functionFlags & FunctionFlags.Generator) === 0) { // Async function or normal function
const returnOrPromisedType = node.type && (functionFlags & FunctionFlags.Async
const returnOrPromisedType = returnTypeNode && (functionFlags & FunctionFlags.Async
? checkAsyncFunctionReturnType(node) // Async function
: getTypeFromTypeNode(node.type)); // normal function
: getTypeFromTypeNode(returnTypeNode)); // normal function
checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType);
}
if (produceDiagnostics && !node.type) {
if (produceDiagnostics && !returnTypeNode) {
// Report an implicit any error if there is no body, no explicit return type, and node is not a private method
// in an ambient context
if (noImplicitAny && nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) {
@@ -19559,9 +19554,7 @@ namespace ts {
function errorUnusedLocal(node: Node, name: string) {
if (isIdentifierThatStartsWithUnderScore(node)) {
const declaration = getRootDeclaration(node.parent);
if (declaration.kind === SyntaxKind.VariableDeclaration &&
(declaration.parent.parent.kind === SyntaxKind.ForInStatement ||
declaration.parent.parent.kind === SyntaxKind.ForOfStatement)) {
if (declaration.kind === SyntaxKind.VariableDeclaration && isForInOrOfStatement(declaration.parent.parent)) {
return;
}
}
@@ -20254,7 +20247,7 @@ namespace ts {
}
}
function checkForInOrForOfVariableDeclaration(iterationStatement: ForInStatement | ForOfStatement): void {
function checkForInOrForOfVariableDeclaration(iterationStatement: ForInOrOfStatement): void {
const variableDeclarationList = <VariableDeclarationList>iterationStatement.initializer;
// checkGrammarForInOrForOfStatement will check that there is exactly one declaration.
if (variableDeclarationList.declarations.length >= 1) {
@@ -20584,7 +20577,8 @@ namespace ts {
}
function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) {
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(node.symbol, SyntaxKind.SetAccessor)));
return node.kind === SyntaxKind.GetAccessor
&& getEffectiveSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(node.symbol, SyntaxKind.SetAccessor)) !== undefined;
}
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
@@ -20628,7 +20622,7 @@ namespace ts {
error(node, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
}
}
else if (func.type || isGetAccessorWithAnnotatedSetAccessor(func)) {
else if (getEffectiveReturnTypeNode(func) || isGetAccessorWithAnnotatedSetAccessor(func)) {
if (functionFlags & FunctionFlags.Async) { // Async function
const promisedType = getPromisedTypeOfPromise(returnType);
const awaitedType = checkAwaitedType(exprType, node, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
@@ -21766,7 +21760,10 @@ namespace ts {
}
// Don't allow to re-export something with no value side when `--isolatedModules` is set.
if (node.kind === SyntaxKind.ExportSpecifier && compilerOptions.isolatedModules && !(target.flags & SymbolFlags.Value)) {
if (compilerOptions.isolatedModules
&& node.kind === SyntaxKind.ExportSpecifier
&& !(target.flags & SymbolFlags.Value)
&& !isInAmbientContext(node)) {
error(node, Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided);
}
}
@@ -22528,10 +22525,16 @@ namespace ts {
}
if (entityName.parent!.kind === SyntaxKind.JSDocParameterTag) {
const parameter = ts.getParameterFromJSDoc(entityName.parent as JSDocParameterTag);
const parameter = getParameterFromJSDoc(entityName.parent as JSDocParameterTag);
return parameter && parameter.symbol;
}
if (entityName.parent.kind === SyntaxKind.TypeParameter && entityName.parent.parent.kind === SyntaxKind.JSDocTemplateTag) {
Debug.assert(!isInJavaScriptFile(entityName)); // Otherwise `isDeclarationName` would have been true.
const typeParameter = getTypeParameterFromJsDoc(entityName.parent as TypeParameterDeclaration & { parent: JSDocTemplateTag });
return typeParameter && typeParameter.symbol;
}
if (isPartOfExpression(entityName)) {
if (nodeIsMissing(entityName)) {
// Missing entity name.
@@ -24224,7 +24227,7 @@ namespace ts {
}
}
function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInStatement | ForOfStatement): boolean {
function checkGrammarForInOrForOfStatement(forInOrOfStatement: ForInOrOfStatement): boolean {
if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
return true;
}
@@ -24792,13 +24795,9 @@ namespace ts {
switch (name.parent.kind) {
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
if ((name.parent as ImportOrExportSpecifier).propertyName) {
return true;
}
// falls through
return true;
default:
return isDeclarationName(name);
}
}
}
+6
View File
@@ -620,6 +620,12 @@ namespace ts {
category: Diagnostics.Advanced_Options,
description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
},
{
name: "noStrictGenericChecks",
type: "boolean",
category: Diagnostics.Advanced_Options,
description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
},
{
// A list of plugins to load in the language service
name: "plugins",
+11 -25
View File
@@ -2131,13 +2131,13 @@ namespace ts {
export function getScriptKindFromFileName(fileName: string): ScriptKind {
const ext = fileName.substr(fileName.lastIndexOf("."));
switch (ext.toLowerCase()) {
case ".js":
case Extension.Js:
return ScriptKind.JS;
case ".jsx":
case Extension.Jsx:
return ScriptKind.JSX;
case ".ts":
case Extension.Ts:
return ScriptKind.TS;
case ".tsx":
case Extension.Tsx:
return ScriptKind.TSX;
default:
return ScriptKind.Unknown;
@@ -2147,10 +2147,10 @@ namespace ts {
/**
* List of supported extensions in order of file resolution precedence.
*/
export const supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"];
export const supportedTypeScriptExtensions = [Extension.Ts, Extension.Tsx, Extension.Dts];
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
export const supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"];
export const supportedJavascriptExtensions = [".js", ".jsx"];
export const supportedTypescriptExtensionsForExtractExtension = [Extension.Dts, Extension.Ts, Extension.Tsx];
export const supportedJavascriptExtensions = [Extension.Js, Extension.Jsx];
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: JsFileExtensionInfo[]): string[] {
@@ -2158,7 +2158,7 @@ namespace ts {
if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) {
return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions;
}
const extensions = allSupportedExtensions.slice(0);
const extensions: string[] = allSupportedExtensions.slice(0);
for (const extInfo of extraFileExtensions) {
if (extensions.indexOf(extInfo.extension) === -1) {
extensions.push(extInfo.extension);
@@ -2237,7 +2237,7 @@ namespace ts {
}
}
const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"];
const extensionsToRemove = [Extension.Dts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx];
export function removeFileExtension(path: string): string {
for (const ext of extensionsToRemove) {
const extensionless = tryRemoveExtension(path, ext);
@@ -2491,7 +2491,7 @@ namespace ts {
/** True if an extension is one of the supported TypeScript extensions. */
export function extensionIsTypeScript(ext: Extension): boolean {
return ext <= Extension.LastTypeScriptExtension;
return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts;
}
/**
@@ -2506,21 +2506,7 @@ namespace ts {
Debug.fail(`File ${path} has unknown extension.`);
}
export function tryGetExtensionFromPath(path: string): Extension | undefined {
if (fileExtensionIs(path, ".d.ts")) {
return Extension.Dts;
}
if (fileExtensionIs(path, ".ts")) {
return Extension.Ts;
}
if (fileExtensionIs(path, ".tsx")) {
return Extension.Tsx;
}
if (fileExtensionIs(path, ".js")) {
return Extension.Js;
}
if (fileExtensionIs(path, ".jsx")) {
return Extension.Jsx;
}
return find(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e));
}
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
+1 -1
View File
@@ -596,7 +596,7 @@ namespace ts {
currentIdentifiers = node.identifiers;
isCurrentFileExternalModule = isExternalModule(node);
enclosingDeclaration = node;
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComents*/ true);
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComments*/ true);
emitLines(node.statements);
}
+4
View File
@@ -3278,6 +3278,10 @@
"category": "Message",
"code": 6184
},
"Disable strict checking of generic signatures in function types.": {
"category": "Message",
"code": 6185
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
+5 -5
View File
@@ -815,15 +815,15 @@ namespace ts {
switch (extensions) {
case Extensions.DtsOnly:
return tryExtension(".d.ts", Extension.Dts);
return tryExtension(Extension.Dts);
case Extensions.TypeScript:
return tryExtension(".ts", Extension.Ts) || tryExtension(".tsx", Extension.Tsx) || tryExtension(".d.ts", Extension.Dts);
return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts);
case Extensions.JavaScript:
return tryExtension(".js", Extension.Js) || tryExtension(".jsx", Extension.Jsx);
return tryExtension(Extension.Js) || tryExtension(Extension.Jsx);
}
function tryExtension(ext: string, extension: Extension): Resolved | undefined {
const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
function tryExtension(extension: Extension): Resolved | undefined {
const path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state);
return path && { path, extension };
}
}
+4 -4
View File
@@ -15,7 +15,7 @@ namespace ts {
else if (kind === SyntaxKind.Identifier) {
return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, pos, end);
}
else if (kind < SyntaxKind.FirstNode) {
else if (!isNodeKind(kind)) {
return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, pos, end);
}
else {
@@ -764,7 +764,7 @@ namespace ts {
sourceFile.languageVersion = languageVersion;
sourceFile.fileName = normalizePath(fileName);
sourceFile.languageVariant = getLanguageVariant(scriptKind);
sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, ".d.ts");
sourceFile.isDeclarationFile = fileExtensionIs(sourceFile.fileName, Extension.Dts);
sourceFile.scriptKind = scriptKind;
return sourceFile;
@@ -1103,7 +1103,7 @@ namespace ts {
pos = scanner.getStartPos();
}
return kind >= SyntaxKind.FirstNode ? new NodeConstructor(kind, pos, pos) :
return isNodeKind(kind) ? new NodeConstructor(kind, pos, pos) :
kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, pos, pos) :
new TokenConstructor(kind, pos, pos);
}
@@ -6851,7 +6851,7 @@ namespace ts {
jsDocNamespaceNode.flags |= flags;
jsDocNamespaceNode.name = typeNameOrNamespaceName;
jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(NodeFlags.NestedNamespace);
return jsDocNamespaceNode;
return finishNode(jsDocNamespaceNode);
}
if (typeNameOrNamespaceName && flags & NodeFlags.NestedNamespace) {
+1 -1
View File
@@ -1495,7 +1495,7 @@ namespace ts {
}
const sourceFileWithAddedExtension = forEach(supportedExtensions, extension => getSourceFile(fileName + extension));
if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.File_0_not_found, fileName + ".ts");
if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.File_0_not_found, fileName + Extension.Ts);
return sourceFileWithAddedExtension;
}
}
+4
View File
@@ -35,6 +35,10 @@ namespace ts {
getDirectories(path: string): string[];
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[];
getModifiedTime?(path: string): Date;
/**
* This should be cryptographically secure.
* A good implementation is node.js' `crypto.createHash`. (https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm)
*/
createHash?(data: string): string;
getMemoryUsage?(): number;
exit(exitCode?: number): void;
+1 -1
View File
@@ -239,7 +239,7 @@ namespace ts {
function hoistVariableDeclaration(name: Identifier): void {
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
const decl = createVariableDeclaration(name);
const decl = setEmitFlags(createVariableDeclaration(name), EmitFlags.NoNestedSourceMaps);
if (!lexicalEnvironmentVariableDeclarations) {
lexicalEnvironmentVariableDeclarations = [decl];
}
+13 -7
View File
@@ -640,10 +640,13 @@ namespace ts {
return undefined;
}
return createStatement(
inlineExpressions(
map(variables, transformInitializedVariable)
)
return setSourceMapRange(
createStatement(
inlineExpressions(
map(variables, transformInitializedVariable)
)
),
node
);
}
}
@@ -1281,9 +1284,12 @@ namespace ts {
}
function transformInitializedVariable(node: VariableDeclaration) {
return createAssignment(
<Identifier>getSynthesizedClone(node.name),
visitNode(node.initializer, visitor, isExpression)
return setSourceMapRange(
createAssignment(
setSourceMapRange(<Identifier>getSynthesizedClone(node.name), node.name),
visitNode(node.initializer, visitor, isExpression)
),
node
);
}
+4
View File
@@ -662,6 +662,10 @@ namespace ts {
}
}
if (ts.Debug.isDebugging) {
ts.Debug.enableDebugInfo();
}
if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) {
ts.sys.tryEnableSourceMapsForHost();
}
+10 -8
View File
@@ -1708,6 +1708,8 @@ namespace ts {
incrementor?: Expression;
}
export type ForInOrOfStatement = ForInStatement | ForOfStatement;
export interface ForInStatement extends IterationStatement {
kind: SyntaxKind.ForInStatement;
initializer: ForInitializer;
@@ -1797,7 +1799,7 @@ namespace ts {
block: Block;
}
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration;
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
export interface ClassLikeDeclaration extends NamedDeclaration {
name?: Identifier;
@@ -3522,6 +3524,7 @@ namespace ts {
noImplicitAny?: boolean; // Always combine with strict property
noImplicitReturns?: boolean;
noImplicitThis?: boolean; // Always combine with strict property
noStrictGenericChecks?: boolean;
noUnusedLocals?: boolean;
noUnusedParameters?: boolean;
noImplicitUseStrict?: boolean;
@@ -3881,13 +3884,12 @@ namespace ts {
extension: Extension;
}
export enum Extension {
Ts,
Tsx,
Dts,
Js,
Jsx,
LastTypeScriptExtension = Dts
export const enum Extension {
Ts = ".ts",
Tsx = ".tsx",
Dts = ".d.ts",
Js = ".js",
Jsx = ".jsx"
}
export interface ResolvedModuleWithFailedLookupLocations {
+102 -13
View File
@@ -1448,7 +1448,7 @@ namespace ts {
return node && firstOrUndefined(getJSDocTags(node, kind));
}
export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
export function getJSDocs(node: Node): (JSDoc | JSDocTag)[] {
if (isJSDocTypedefTag(node)) {
return [node.parent];
}
@@ -1546,6 +1546,12 @@ namespace ts {
p.name.kind === SyntaxKind.Identifier && p.name.text === name);
}
export function getTypeParameterFromJsDoc(node: TypeParameterDeclaration & { parent: JSDocTemplateTag }): TypeParameterDeclaration | undefined {
const name = node.name.text;
const { typeParameters } = (node.parent.parent.parent as ts.SignatureDeclaration | ts.InterfaceDeclaration | ts.ClassDeclaration);
return find(typeParameters, p => p.name.text === name);
}
export function getJSDocType(node: Node): JSDocType {
let tag: JSDocTypeTag | JSDocParameterTag = getFirstJSDocTag(node, SyntaxKind.JSDocTypeTag) as JSDocTypeTag;
if (!tag && node.kind === SyntaxKind.Parameter) {
@@ -1570,6 +1576,11 @@ namespace ts {
return getFirstJSDocTag(node, SyntaxKind.JSDocReturnTag) as JSDocReturnTag;
}
export function getJSDocReturnType(node: Node): JSDocType {
const returnTag = getJSDocReturnTag(node);
return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
}
export function getJSDocTemplateTag(node: Node): JSDocTemplateTag {
return getFirstJSDocTag(node, SyntaxKind.JSDocTemplateTag) as JSDocTemplateTag;
}
@@ -1616,7 +1627,7 @@ namespace ts {
return unaryOperator === SyntaxKind.PlusPlusToken || unaryOperator === SyntaxKind.MinusMinusToken ? AssignmentKind.Compound : AssignmentKind.None;
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
return (<ForInStatement | ForOfStatement>parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None;
return (<ForInOrOfStatement>parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None;
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.ArrayLiteralExpression:
case SyntaxKind.SpreadElement:
@@ -2490,7 +2501,7 @@ namespace ts {
const path = outputDir
? getSourceFilePathInNewDir(sourceFile, host, outputDir)
: sourceFile.fileName;
return removeFileExtension(path) + ".d.ts";
return removeFileExtension(path) + Extension.Dts;
}
export interface EmitFileNames {
@@ -2549,7 +2560,7 @@ namespace ts {
if (sourceFiles.length) {
const jsFilePath = options.outFile || options.out;
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + ".d.ts" : "";
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : "";
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
}
}
@@ -2570,19 +2581,19 @@ namespace ts {
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): string {
function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): Extension {
if (options.jsx === JsxEmit.Preserve) {
if (isSourceFileJavaScript(sourceFile)) {
if (fileExtensionIs(sourceFile.fileName, ".jsx")) {
return ".jsx";
if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) {
return Extension.Jsx;
}
}
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
// TypeScript source file preserving JSX syntax
return ".jsx";
return Extension.Jsx;
}
}
return ".js";
return Extension.Js;
}
export function getSourceFilePathInNewDir(sourceFile: SourceFile, host: EmitHost, newDirPath: string) {
@@ -2615,14 +2626,19 @@ namespace ts {
});
}
/** Get the type annotaion for the value parameter. */
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
function getSetAccessorValueParameter(accessor: SetAccessorDeclaration): ParameterDeclaration | undefined {
if (accessor && accessor.parameters.length > 0) {
const hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
return accessor.parameters[hasThis ? 1 : 0].type;
return accessor.parameters[hasThis ? 1 : 0];
}
}
/** Get the type annotation for the value parameter. */
export function getSetAccessorTypeAnnotationNode(accessor: SetAccessorDeclaration): TypeNode {
const parameter = getSetAccessorValueParameter(accessor);
return parameter && parameter.type;
}
export function getThisParameter(signature: SignatureDeclaration): ParameterDeclaration | undefined {
if (signature.parameters.length) {
const thisParameter = signature.parameters[0];
@@ -2701,6 +2717,55 @@ namespace ts {
};
}
/**
* Gets the effective type annotation of a variable, parameter, or property. If the node was
* parsed in a JavaScript file, gets the type annotation from JSDoc.
*/
export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration): TypeNode {
if (node.type) {
return node.type;
}
if (node.flags & NodeFlags.JavaScriptFile) {
return getJSDocType(node);
}
}
/**
* Gets the effective return type annotation of a signature. If the node was parsed in a
* JavaScript file, gets the return type annotation from JSDoc.
*/
export function getEffectiveReturnTypeNode(node: SignatureDeclaration): TypeNode {
if (node.type) {
return node.type;
}
if (node.flags & NodeFlags.JavaScriptFile) {
return getJSDocReturnType(node);
}
}
/**
* Gets the effective type parameters. If the node was parsed in a
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
*/
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): TypeParameterDeclaration[] {
if (node.typeParameters) {
return node.typeParameters;
}
if (node.flags & NodeFlags.JavaScriptFile) {
const templateTag = getJSDocTemplateTag(node);
return templateTag && templateTag.typeParameters;
}
}
/**
* Gets the effective type annotation of the value parameter of a set accessor. If the node
* was parsed in a JavaScript file, gets the type annotation from JSDoc.
*/
export function getEffectiveSetAccessorTypeAnnotationNode(node: SetAccessorDeclaration): TypeNode {
const parameter = getSetAccessorValueParameter(node);
return parameter && getEffectiveTypeAnnotationNode(parameter);
}
export function emitNewLineBeforeLeadingComments(lineMap: number[], writer: EmitTextWriter, node: TextRange, leadingComments: CommentRange[]) {
emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
}
@@ -4047,7 +4112,7 @@ namespace ts {
// Signature elements
export function isTypeParameter(node: Node): node is TypeParameterDeclaration {
export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration {
return node.kind === SyntaxKind.TypeParameter;
}
@@ -4670,6 +4735,16 @@ namespace ts {
// All node tests in the following list should *not* reference parent pointers so that
// they may be used with transformations.
namespace ts {
/* @internal */
export function isNode(node: Node) {
return isNodeKind(node.kind);
}
/* @internal */
export function isNodeKind(kind: SyntaxKind) {
return kind >= SyntaxKind.FirstNode;
}
/**
* True if node is of some token syntax kind.
* For example, this is true for an IfKeyword but not for an IfStatement.
@@ -5091,6 +5166,11 @@ namespace ts {
return false;
}
/* @internal */
export function isForInOrOfStatement(node: Node): node is ForInOrOfStatement {
return node.kind === SyntaxKind.ForInStatement || node.kind === SyntaxKind.ForOfStatement;
}
// Element
/* @internal */
@@ -5219,6 +5299,10 @@ namespace ts {
/* @internal */
export function isDeclaration(node: Node): node is NamedDeclaration {
if (node.kind === SyntaxKind.TypeParameter) {
return node.parent.kind !== SyntaxKind.JSDocTemplateTag || isInJavaScriptFile(node);
}
return isDeclarationKind(node.kind);
}
@@ -5308,6 +5392,11 @@ namespace ts {
return node.kind >= SyntaxKind.FirstJSDocNode && node.kind <= SyntaxKind.LastJSDocNode;
}
/** True if node is of a kind that may contain comment text. */
export function isJSDocCommentContainingNode(node: Node): boolean {
return node.kind === SyntaxKind.JSDocComment || isJSDocTag(node);
}
// TODO: determine what this does before making it public.
/* @internal */
export function isJSDocTag(node: Node): boolean {
+64 -46
View File
@@ -275,7 +275,7 @@ namespace ts {
case SyntaxKind.MethodSignature:
return updateMethodSignature(<MethodSignature>node,
nodesVisitor((<MethodSignature>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<MethodSignature>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<MethodSignature>node).parameters, visitor, isParameterDeclaration),
visitNode((<MethodSignature>node).type, visitor, isTypeNode),
visitNode((<MethodSignature>node).name, visitor, isPropertyName),
@@ -288,7 +288,7 @@ namespace ts {
visitNode((<MethodDeclaration>node).asteriskToken, tokenVisitor, isToken),
visitNode((<MethodDeclaration>node).name, visitor, isPropertyName),
visitNode((<MethodDeclaration>node).questionToken, tokenVisitor, isToken),
nodesVisitor((<MethodDeclaration>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<MethodDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
visitParameterList((<MethodDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<MethodDeclaration>node).type, visitor, isTypeNode),
visitFunctionBody((<MethodDeclaration>node).body, visitor, context));
@@ -319,13 +319,13 @@ namespace ts {
case SyntaxKind.CallSignature:
return updateCallSignature(<CallSignatureDeclaration>node,
nodesVisitor((<CallSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<CallSignatureDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<CallSignatureDeclaration>node).parameters, visitor, isParameterDeclaration),
visitNode((<CallSignatureDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.ConstructSignature:
return updateConstructSignature(<ConstructSignatureDeclaration>node,
nodesVisitor((<ConstructSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<ConstructSignatureDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<ConstructSignatureDeclaration>node).parameters, visitor, isParameterDeclaration),
visitNode((<ConstructSignatureDeclaration>node).type, visitor, isTypeNode));
@@ -350,13 +350,13 @@ namespace ts {
case SyntaxKind.FunctionType:
return updateFunctionTypeNode(<FunctionTypeNode>node,
nodesVisitor((<FunctionTypeNode>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<FunctionTypeNode>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<FunctionTypeNode>node).parameters, visitor, isParameterDeclaration),
visitNode((<FunctionTypeNode>node).type, visitor, isTypeNode));
case SyntaxKind.ConstructorType:
return updateConstructorTypeNode(<ConstructorTypeNode>node,
nodesVisitor((<ConstructorTypeNode>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<ConstructorTypeNode>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<ConstructorTypeNode>node).parameters, visitor, isParameterDeclaration),
visitNode((<ConstructorTypeNode>node).type, visitor, isTypeNode));
@@ -400,7 +400,7 @@ namespace ts {
case SyntaxKind.MappedType:
return updateMappedTypeNode((<MappedTypeNode>node),
visitNode((<MappedTypeNode>node).readonlyToken, tokenVisitor, isToken),
visitNode((<MappedTypeNode>node).typeParameter, visitor, isTypeParameter),
visitNode((<MappedTypeNode>node).typeParameter, visitor, isTypeParameterDeclaration),
visitNode((<MappedTypeNode>node).questionToken, tokenVisitor, isToken),
visitNode((<MappedTypeNode>node).type, visitor, isTypeNode));
@@ -476,7 +476,7 @@ namespace ts {
nodesVisitor((<FunctionExpression>node).modifiers, visitor, isModifier),
visitNode((<FunctionExpression>node).asteriskToken, tokenVisitor, isToken),
visitNode((<FunctionExpression>node).name, visitor, isIdentifier),
nodesVisitor((<FunctionExpression>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<FunctionExpression>node).typeParameters, visitor, isTypeParameterDeclaration),
visitParameterList((<FunctionExpression>node).parameters, visitor, context, nodesVisitor),
visitNode((<FunctionExpression>node).type, visitor, isTypeNode),
visitFunctionBody((<FunctionExpression>node).body, visitor, context));
@@ -484,7 +484,7 @@ namespace ts {
case SyntaxKind.ArrowFunction:
return updateArrowFunction(<ArrowFunction>node,
nodesVisitor((<ArrowFunction>node).modifiers, visitor, isModifier),
nodesVisitor((<ArrowFunction>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<ArrowFunction>node).typeParameters, visitor, isTypeParameterDeclaration),
visitParameterList((<ArrowFunction>node).parameters, visitor, context, nodesVisitor),
visitNode((<ArrowFunction>node).type, visitor, isTypeNode),
visitFunctionBody((<ArrowFunction>node).body, visitor, context));
@@ -543,7 +543,7 @@ namespace ts {
return updateClassExpression(<ClassExpression>node,
nodesVisitor((<ClassExpression>node).modifiers, visitor, isModifier),
visitNode((<ClassExpression>node).name, visitor, isIdentifier),
nodesVisitor((<ClassExpression>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<ClassExpression>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<ClassExpression>node).heritageClauses, visitor, isHeritageClause),
nodesVisitor((<ClassExpression>node).members, visitor, isClassElement));
@@ -676,7 +676,7 @@ namespace ts {
nodesVisitor((<FunctionDeclaration>node).modifiers, visitor, isModifier),
visitNode((<FunctionDeclaration>node).asteriskToken, tokenVisitor, isToken),
visitNode((<FunctionDeclaration>node).name, visitor, isIdentifier),
nodesVisitor((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
visitParameterList((<FunctionDeclaration>node).parameters, visitor, context, nodesVisitor),
visitNode((<FunctionDeclaration>node).type, visitor, isTypeNode),
visitFunctionBody((<FunctionExpression>node).body, visitor, context));
@@ -686,7 +686,7 @@ namespace ts {
nodesVisitor((<ClassDeclaration>node).decorators, visitor, isDecorator),
nodesVisitor((<ClassDeclaration>node).modifiers, visitor, isModifier),
visitNode((<ClassDeclaration>node).name, visitor, isIdentifier),
nodesVisitor((<ClassDeclaration>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<ClassDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<ClassDeclaration>node).heritageClauses, visitor, isHeritageClause),
nodesVisitor((<ClassDeclaration>node).members, visitor, isClassElement));
@@ -695,7 +695,7 @@ namespace ts {
nodesVisitor((<InterfaceDeclaration>node).decorators, visitor, isDecorator),
nodesVisitor((<InterfaceDeclaration>node).modifiers, visitor, isModifier),
visitNode((<InterfaceDeclaration>node).name, visitor, isIdentifier),
nodesVisitor((<InterfaceDeclaration>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<InterfaceDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
nodesVisitor((<InterfaceDeclaration>node).heritageClauses, visitor, isHeritageClause),
nodesVisitor((<InterfaceDeclaration>node).members, visitor, isTypeElement));
@@ -704,7 +704,7 @@ namespace ts {
nodesVisitor((<TypeAliasDeclaration>node).decorators, visitor, isDecorator),
nodesVisitor((<TypeAliasDeclaration>node).modifiers, visitor, isModifier),
visitNode((<TypeAliasDeclaration>node).name, visitor, isIdentifier),
nodesVisitor((<TypeAliasDeclaration>node).typeParameters, visitor, isTypeParameter),
nodesVisitor((<TypeAliasDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
visitNode((<TypeAliasDeclaration>node).type, visitor, isTypeNode));
case SyntaxKind.EnumDeclaration:
@@ -1198,9 +1198,9 @@ namespace ts {
case SyntaxKind.ForInStatement:
case SyntaxKind.ForOfStatement:
result = reduceNode((<ForInStatement | ForOfStatement>node).initializer, cbNode, result);
result = reduceNode((<ForInStatement | ForOfStatement>node).expression, cbNode, result);
result = reduceNode((<ForInStatement | ForOfStatement>node).statement, cbNode, result);
result = reduceNode((<ForInOrOfStatement>node).initializer, cbNode, result);
result = reduceNode((<ForInOrOfStatement>node).expression, cbNode, result);
result = reduceNode((<ForInOrOfStatement>node).statement, cbNode, result);
break;
case SyntaxKind.ReturnStatement:
@@ -1517,35 +1517,7 @@ namespace ts {
}
export namespace Debug {
if (isDebugging) {
// Add additional properties in debug mode to assist with debugging.
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
"__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
});
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
"__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } },
"__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
"__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } },
});
for (const ctor of [objectAllocator.getNodeConstructor(), objectAllocator.getIdentifierConstructor(), objectAllocator.getTokenConstructor(), objectAllocator.getSourceFileConstructor()]) {
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
Object.defineProperties(ctor.prototype, {
"__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } },
"__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
"__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
"__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
"__debugGetText": { value(this: Node, includeTrivia?: boolean) {
if (nodeIsSynthesized(this)) return "";
const parseNode = getParseTreeNode(this);
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
} }
});
}
}
}
let isDebugInfoEnabled = false;
export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal)
? (node: Node, message?: string): void => fail(
@@ -1592,5 +1564,51 @@ namespace ts {
() => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`,
assertMissingNode)
: noop;
/**
* Injects debug information into frequently used types.
*/
export function enableDebugInfo() {
if (isDebugInfoEnabled) return;
// Add additional properties in debug mode to assist with debugging.
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
"__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
});
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
"__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } },
"__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
"__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } },
});
const nodeConstructors = [
objectAllocator.getNodeConstructor(),
objectAllocator.getIdentifierConstructor(),
objectAllocator.getTokenConstructor(),
objectAllocator.getSourceFileConstructor()
];
for (const ctor of nodeConstructors) {
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
Object.defineProperties(ctor.prototype, {
"__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } },
"__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
"__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
"__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
"__debugGetText": {
value(this: Node, includeTrivia?: boolean) {
if (nodeIsSynthesized(this)) return "";
const parseNode = getParseTreeNode(this);
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
}
}
});
}
}
isDebugInfoEnabled = true;
}
}
}
+1 -1
View File
@@ -90,7 +90,7 @@ class CompilerBaselineRunner extends RunnerBase {
}
lastUnit = units[units.length - 1];
hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ".d.ts"));
hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ts.Extension.Dts));
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
// otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another.
+21 -5
View File
@@ -536,11 +536,16 @@ namespace FourSlash {
Harness.IO.log("Unexpected error(s) found. Error list is:");
}
for (const { start, length, messageText } of errors) {
Harness.IO.log(" minChar: " + start +
", limChar: " + (start + length) +
for (const { start, length, messageText, file } of errors) {
Harness.IO.log(" from: " + showPosition(file, start) +
", to: " + showPosition(file, start + length) +
", message: " + ts.flattenDiagnosticMessageText(messageText, Harness.IO.newLine()) + "\n");
}
function showPosition(file: ts.SourceFile, pos: number) {
const { line, character } = ts.getLineAndCharacterOfPosition(file, pos);
return `${line}:${character}`;
}
}
public verifyNoErrors() {
@@ -1459,7 +1464,7 @@ namespace FourSlash {
let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile];
if (!baselineFile) {
baselineFile = this.activeFile.fileName.replace(this.basePath + "/breakpointValidation", "bpSpan");
baselineFile = baselineFile.replace(".ts", ".baseline");
baselineFile = baselineFile.replace(ts.Extension.Ts, ".baseline");
}
Harness.Baseline.runBaseline(
@@ -1529,7 +1534,7 @@ namespace FourSlash {
public baselineQuickInfo() {
let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile];
if (!baselineFile) {
baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(".ts", ".baseline");
baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline");
}
Harness.Baseline.runBaseline(
@@ -2671,6 +2676,13 @@ namespace FourSlash {
this.rangesByText().forEach(ranges => this.verifyRangesAreDocumentHighlights(ranges));
}
public verifyDocumentHighlightsOf(startRange: Range, ranges: Range[]) {
ts.Debug.assert(ts.contains(ranges, startRange));
const fileNames = unique(ranges, range => range.fileName);
this.goToRangeStart(startRange);
this.verifyDocumentHighlights(ranges, fileNames);
}
public verifyRangesAreDocumentHighlights(ranges?: Range[]) {
ranges = ranges || this.getRanges();
const fileNames = unique(ranges, range => range.fileName);
@@ -3885,6 +3897,10 @@ namespace FourSlashInterface {
this.state.verifyRangesWithSameTextAreDocumentHighlights();
}
public documentHighlightsOf(startRange: FourSlash.Range, ranges: FourSlash.Range[]) {
this.state.verifyDocumentHighlightsOf(startRange, ranges);
}
public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) {
this.state.verifyCompletionEntryDetails(entryName, text, documentation, kind, tags);
}
+10 -10
View File
@@ -1053,7 +1053,7 @@ namespace Harness {
];
let optionsIndex: ts.Map<ts.CommandLineOption>;
function getCommandLineOption(name: string): ts.CommandLineOption {
function getCommandLineOption(name: string): ts.CommandLineOption | undefined {
if (!optionsIndex) {
optionsIndex = ts.createMap<ts.CommandLineOption>();
const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations);
@@ -1249,7 +1249,7 @@ namespace Harness {
sourceFileName = outFile;
}
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
const dTsFileName = ts.removeFileExtension(sourceFileName) + ts.Extension.Dts;
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
}
@@ -1465,7 +1465,7 @@ namespace Harness {
// When calling this function from rwc-runner, the baselinePath will have no extension.
// As rwc test- file is stored in json which ".json" will get stripped off.
// When calling this function from compiler-runner, the baselinePath will then has either ".ts" or ".tsx" extension
const outputFileName = ts.endsWith(baselinePath, ".ts") || ts.endsWith(baselinePath, ".tsx") ?
const outputFileName = ts.endsWith(baselinePath, ts.Extension.Ts) || ts.endsWith(baselinePath, ts.Extension.Tsx) ?
baselinePath.replace(/\.tsx?/, fullExtension) : baselinePath.concat(fullExtension);
Harness.Baseline.runBaseline(outputFileName, () => fullBaseLine, opts);
}
@@ -1563,7 +1563,7 @@ namespace Harness {
}
// check js output
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js"), () => {
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), () => {
let tsCode = "";
const tsSources = otherFiles.concat(toBeCompiled);
if (tsSources.length > 1) {
@@ -1651,22 +1651,22 @@ namespace Harness {
}
export function isTS(fileName: string) {
return ts.endsWith(fileName, ".ts");
return ts.endsWith(fileName, ts.Extension.Ts);
}
export function isTSX(fileName: string) {
return ts.endsWith(fileName, ".tsx");
return ts.endsWith(fileName, ts.Extension.Tsx);
}
export function isDTS(fileName: string) {
return ts.endsWith(fileName, ".d.ts");
return ts.endsWith(fileName, ts.Extension.Dts);
}
export function isJS(fileName: string) {
return ts.endsWith(fileName, ".js");
return ts.endsWith(fileName, ts.Extension.Js);
}
export function isJSX(fileName: string) {
return ts.endsWith(fileName, ".jsx");
return ts.endsWith(fileName, ts.Extension.Jsx);
}
export function isJSMap(fileName: string) {
@@ -1973,7 +1973,7 @@ namespace Harness {
export function isDefaultLibraryFile(filePath: string): boolean {
// We need to make sure that the filePath is prefixed with "lib." not just containing "lib." and end with ".d.ts"
const fileName = ts.getBaseFileName(ts.normalizeSlashes(filePath));
return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ".d.ts");
return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ts.Extension.Dts);
}
export function isBuiltFile(filePath: string): boolean {
+5 -1
View File
@@ -731,7 +731,7 @@ namespace Harness.LanguageService {
}
createHash(s: string) {
return s;
return mockHash(s);
}
require(_initialDir: string, _moduleName: string): ts.server.RequireResult {
@@ -856,4 +856,8 @@ namespace Harness.LanguageService {
getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); }
getPreProcessedFileInfo(): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
}
export function mockHash(s: string): string {
return `hash-${s}`;
}
}
+4 -4
View File
@@ -325,8 +325,8 @@ class ProjectRunner extends RunnerBase {
// we need to instead create files that can live in the project reference folder
// but make sure extension of these files matches with the fileName the compiler asked to write
diskRelativeName = "diskFile" + nonSubfolderDiskFiles +
(Harness.Compiler.isDTS(fileName) ? ".d.ts" :
Harness.Compiler.isJS(fileName) ? ".js" : ".js.map");
(Harness.Compiler.isDTS(fileName) ? ts.Extension.Dts :
Harness.Compiler.isJS(fileName) ? ts.Extension.Js : ".js.map");
nonSubfolderDiskFiles++;
}
@@ -386,14 +386,14 @@ class ProjectRunner extends RunnerBase {
emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
}
const outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
const outputDtsFileName = emitOutputFilePathWithoutExtension + ts.Extension.Dts;
const file = findOutputDtsFile(outputDtsFileName);
if (file) {
allInputFiles.unshift(file);
}
}
else {
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts";
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ts.Extension.Dts;
const outputDtsFile = findOutputDtsFile(outputDtsFileName);
if (!ts.contains(allInputFiles, outputDtsFile)) {
allInputFiles.unshift(outputDtsFile);
+4
View File
@@ -222,6 +222,10 @@ if (taskConfigsFolder) {
}
}
else {
if (ts.Debug.isDebugging) {
ts.Debug.enableDebugInfo();
}
runTests(runners);
}
if (!runUnitTests) {
@@ -47,7 +47,7 @@ namespace ts {
clearTimeout,
setImmediate: typeof setImmediate !== "undefined" ? setImmediate : action => setTimeout(action, 0),
clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : clearTimeout,
createHash: s => s
createHash: Harness.LanguageService.mockHash,
};
}
+2 -2
View File
@@ -513,7 +513,7 @@ namespace ts.projectSystem {
const lines = ["var x = 1;", "var y = 2;"];
const path = "/a/app";
const f = {
path: path + ".ts",
path: path + ts.Extension.Ts,
content: lines.join(newLine)
};
const host = createServerHost([f], { newLine });
@@ -530,7 +530,7 @@ namespace ts.projectSystem {
command: "compileOnSaveEmitFile",
arguments: { file: f.path }
});
const emitOutput = host.readFile(path + ".js");
const emitOutput = host.readFile(path + ts.Extension.Js);
assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline");
}
});
+1 -1
View File
@@ -5,7 +5,7 @@ namespace ts {
if (!expected === !actual) {
if (expected) {
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${Extension[expected.extension]}' to be equal to '${Extension[actual.extension]}'`);
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${expected.extension}' to be equal to '${actual.extension}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
}
return true;
+1 -1
View File
@@ -25,7 +25,7 @@ namespace ts.server {
clearTimeout: noop,
setImmediate: () => 0,
clearImmediate: noop,
createHash: s => s
createHash: Harness.LanguageService.mockHash,
};
const mockLogger: Logger = {
+25 -24
View File
@@ -9,6 +9,7 @@ namespace ts.projectSystem {
et.service.openClientFile(file.path);
assert.equal(et.getEvents().length, 0);
});
it("only sends an event once", () => {
const file = makeFile("/a.ts");
const tsconfig = makeFile("/tsconfig.json", {});
@@ -46,12 +47,13 @@ namespace ts.projectSystem {
const et = new EventTracker([file1]);
const compilerOptions: ts.CompilerOptions = { strict: true };
const projectFileName = "foo.csproj";
const projectFileName = "/hunter2/foo.csproj";
open();
// TODO: Apparently compilerOptions is mutated, so have to repeat it here!
et.assertProjectInfoTelemetryEvent({
projectId: Harness.LanguageService.mockHash("/hunter2/foo.csproj"),
compilerOptions: { strict: true },
compileOnSave: true,
// These properties can't be present for an external project, so they are undefined instead of false.
@@ -195,6 +197,7 @@ namespace ts.projectSystem {
const et = new EventTracker([jsconfig, file]);
et.service.openClientFile(file.path);
et.assertProjectInfoTelemetryEvent({
projectId: Harness.LanguageService.mockHash("/jsconfig.json"),
fileStats: fileStats({ js: 1 }),
compilerOptions: autoJsCompilerOptions,
typeAcquisition: {
@@ -214,6 +217,7 @@ namespace ts.projectSystem {
et.service.openClientFile(file.path);
et.getEvent<server.ProjectLanguageServiceStateEvent>(server.ProjectLanguageServiceStateEvent, /*mayBeMore*/ true);
et.assertProjectInfoTelemetryEvent({
projectId: Harness.LanguageService.mockHash("/jsconfig.json"),
fileStats: fileStats({ js: 1 }),
compilerOptions: autoJsCompilerOptions,
configFileName: "jsconfig.json",
@@ -248,7 +252,26 @@ namespace ts.projectSystem {
}
assertProjectInfoTelemetryEvent(partial: Partial<server.ProjectInfoTelemetryEventData>): void {
assert.deepEqual(this.getEvent<server.ProjectInfoTelemetryEvent>(ts.server.ProjectInfoTelemetryEvent), makePayload(partial));
assert.deepEqual(this.getEvent<server.ProjectInfoTelemetryEvent>(ts.server.ProjectInfoTelemetryEvent), {
projectId: Harness.LanguageService.mockHash("/tsconfig.json"),
fileStats: fileStats({ ts: 1 }),
compilerOptions: {},
extends: false,
files: false,
include: false,
exclude: false,
compileOnSave: false,
typeAcquisition: {
enable: false,
exclude: false,
include: false,
},
configFileName: "tsconfig.json",
projectType: "configured",
languageServiceEnabled: true,
version: ts.version,
...partial,
});
}
getEvent<T extends server.ProjectServiceEvent>(eventName: T["eventName"], mayBeMore = false): T["data"] {
@@ -260,28 +283,6 @@ namespace ts.projectSystem {
}
}
function makePayload(partial: Partial<server.ProjectInfoTelemetryEventData>): server.ProjectInfoTelemetryEventData {
return {
fileStats: fileStats({ ts: 1 }),
compilerOptions: {},
extends: false,
files: false,
include: false,
exclude: false,
compileOnSave: false,
typeAcquisition: {
enable: false,
exclude: false,
include: false,
},
configFileName: "tsconfig.json",
projectType: "configured",
languageServiceEnabled: true,
version: ts.version,
...partial
};
}
function makeFile(path: string, content: {} = ""): projectSystem.FileOrFolder {
return { path, content: typeof content === "string" ? "" : JSON.stringify(content) };
}
+2 -2
View File
@@ -36,7 +36,7 @@ namespace ts {
transpileOptions.reportDiagnostics = true;
justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? ".tsx" : ".ts");
justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? Extension.Tsx : Extension.Ts);
toBeCompiled = [{
unitName: transpileOptions.fileName,
content: input
@@ -88,7 +88,7 @@ namespace ts {
}
it("Correct output for " + justName, () => {
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".js"), () => {
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ts.Extension.Js), () => {
if (transpileResult.outputText) {
return transpileResult.outputText;
}
@@ -472,7 +472,7 @@ namespace ts.projectSystem {
}
createHash(s: string): string {
return s;
return Harness.LanguageService.mockHash(s);
}
triggerDirectoryWatcherCallback(directoryName: string, fileName: string): void {
+2 -1
View File
@@ -3483,7 +3483,7 @@ interface DragEvent extends MouseEvent {
declare var DragEvent: {
prototype: DragEvent;
new(): DragEvent;
new(type: "drag" | "dragend" | "dragenter" | "dragexit" | "dragleave" | "dragover" | "dragstart" | "drop", dragEventInit?: { dataTransfer?: DataTransfer }): DragEvent;
};
interface DynamicsCompressorNode extends AudioNode {
@@ -8224,6 +8224,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte
readonly serviceWorker: ServiceWorkerContainer;
readonly webdriver: boolean;
readonly hardwareConcurrency: number;
readonly languages: string[];
getGamepads(): Gamepad[];
javaEnabled(): boolean;
msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
+3
View File
@@ -37,6 +37,8 @@ namespace ts.server {
}
export interface ProjectInfoTelemetryEventData {
/** Cryptographically secure hash of project file location. */
readonly projectId: string;
/** Count of file extensions seen in the project. */
readonly fileStats: FileStats;
/**
@@ -1049,6 +1051,7 @@ namespace ts.server {
if (!this.eventHandler) return;
const data: ProjectInfoTelemetryEventData = {
projectId: this.host.createHash(projectKey),
fileStats: countEachFileTypes(project.getScriptInfos()),
compilerOptions: convertCompilerOptionsForTelemetry(project.getCompilerOptions()),
typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()),
+1 -1
View File
@@ -25,7 +25,7 @@ namespace ts.server {
result.jsx += 1;
break;
case ScriptKind.TS:
fileExtensionIs(info.fileName, ".d.ts")
fileExtensionIs(info.fileName, Extension.Dts)
? result.dts += 1
: result.ts += 1;
break;
+3 -2
View File
@@ -35,6 +35,7 @@ namespace ts.server {
} = require("os");
function getGlobalTypingsCacheLocation() {
const versionMajorMinor = ts.version.match(/\d+\.\d+/)[0];
switch (process.platform) {
case "win32": {
const basePath = process.env.LOCALAPPDATA ||
@@ -43,7 +44,7 @@ namespace ts.server {
process.env.USERPROFILE ||
(process.env.HOMEDRIVE && process.env.HOMEPATH && normalizeSlashes(process.env.HOMEDRIVE + process.env.HOMEPATH)) ||
os.tmpdir();
return combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript");
return combinePaths(combinePaths(normalizeSlashes(basePath), "Microsoft/TypeScript"), versionMajorMinor);
}
case "openbsd":
case "freebsd":
@@ -51,7 +52,7 @@ namespace ts.server {
case "linux":
case "android": {
const cacheLocation = getNonWindowsCacheLocation(process.platform === "darwin");
return combinePaths(cacheLocation, "typescript");
return combinePaths(combinePaths(cacheLocation, "typescript"), versionMajorMinor);
}
default:
Debug.fail(`unsupported platform '${process.platform}'`);
+8 -2
View File
@@ -112,7 +112,13 @@ namespace ts.server {
return true;
}
export import CommandNames = protocol.CommandTypes;
// CommandNames used to be exposed before TS 2.4 as a namespace
// In TS 2.4 we switched to an enum, keep this for backward compatibility
// The var assignment ensures that even though CommandTypes are a const enum
// we want to ensure the value is maintained in the out since the file is
// built using --preseveConstEnum.
export type CommandNames = protocol.CommandTypes;
export const CommandNames = (<any>protocol).CommandTypes;
export function formatMessage<T extends protocol.Message>(msg: T, logger: server.Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string {
const verboseLogging = logger.hasLevel(LogLevel.verbose);
@@ -1569,7 +1575,7 @@ namespace ts.server {
else {
const info = this.projectService.getScriptInfo(fileNameInProject);
if (!info.isScriptOpen()) {
if (fileNameInProject.indexOf(".d.ts") > 0) {
if (fileNameInProject.indexOf(Extension.Dts) > 0) {
veryLowPriorityFiles.push(fileNameInProject);
}
else {
+1 -1
View File
@@ -146,7 +146,7 @@ namespace ts.BreakpointResolver {
case SyntaxKind.ForOfStatement:
// span in initializer
return spanInInitializerOfForLike(<ForOfStatement | ForInStatement>node);
return spanInInitializerOfForLike(<ForOfStatement>node);
case SyntaxKind.SwitchStatement:
// span on switch(...)
+3 -3
View File
@@ -724,8 +724,8 @@ namespace ts {
pushCommentRange(pos, tag.pos - pos);
}
pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation);
pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName);
pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, ClassificationType.punctuation); // "@"
pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, ClassificationType.docCommentTagName); // e.g. "param"
pos = tag.tagName.end;
@@ -814,7 +814,7 @@ namespace ts {
* False will mean that node is not classified and traverse routine should recurse into node contents.
*/
function tryClassifyNode(node: Node): boolean {
if (isJSDocNode(node)) {
if (isJSDoc(node)) {
return true;
}
+27 -32
View File
@@ -445,7 +445,7 @@ namespace ts.Completions {
}
start = timestamp();
const previousToken = findPrecedingToken(position, sourceFile);
const previousToken = findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*includeJsDoc*/ true);
log("getCompletionData: Get previous token 1: " + (timestamp() - start));
// The decision to provide completion depends on the contextToken, which is determined through the previousToken.
@@ -456,7 +456,7 @@ namespace ts.Completions {
// Skip this partial identifier and adjust the contextToken to the token that precedes it.
if (contextToken && position <= contextToken.end && isWord(contextToken.kind)) {
const start = timestamp();
contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile);
contextToken = findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined, /*includeJsDoc*/ true);
log("getCompletionData: Get previous token 2: " + (timestamp() - start));
}
@@ -844,7 +844,7 @@ namespace ts.Completions {
*
* @returns true if 'symbols' was successfully populated; false otherwise.
*/
function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | BindingPattern): boolean {
function tryGetObjectLikeCompletionSymbols(objectLikeContainer: ObjectLiteralExpression | ObjectBindingPattern): boolean {
// We're looking up possible property names from contextual/inferred/declared type.
isMemberCompletion = true;
@@ -860,41 +860,36 @@ namespace ts.Completions {
typeMembers = typeChecker.getAllPossiblePropertiesOfType(typeForObject);
existingMembers = (<ObjectLiteralExpression>objectLikeContainer).properties;
}
else if (objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern) {
else {
Debug.assert(objectLikeContainer.kind === SyntaxKind.ObjectBindingPattern);
// We are *only* completing on properties from the type being destructured.
isNewIdentifierLocation = false;
const rootDeclaration = getRootDeclaration(objectLikeContainer.parent);
if (isVariableLike(rootDeclaration)) {
// We don't want to complete using the type acquired by the shape
// of the binding pattern; we are only interested in types acquired
// through type declaration or inference.
// Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
// type of parameter will flow in from the contextual type of the function
let canGetType = !!(rootDeclaration.initializer || rootDeclaration.type);
if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) {
if (isExpression(rootDeclaration.parent)) {
canGetType = !!typeChecker.getContextualType(<Expression>rootDeclaration.parent);
}
else if (rootDeclaration.parent.kind === SyntaxKind.MethodDeclaration || rootDeclaration.parent.kind === SyntaxKind.SetAccessor) {
canGetType = isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(<Expression>rootDeclaration.parent.parent);
}
if (!isVariableLike(rootDeclaration)) throw Debug.fail("Root declaration is not variable-like.");
// We don't want to complete using the type acquired by the shape
// of the binding pattern; we are only interested in types acquired
// through type declaration or inference.
// Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
// type of parameter will flow in from the contextual type of the function
let canGetType = rootDeclaration.initializer || rootDeclaration.type || rootDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement;
if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) {
if (isExpression(rootDeclaration.parent)) {
canGetType = !!typeChecker.getContextualType(<Expression>rootDeclaration.parent);
}
if (canGetType) {
const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
if (!typeForObject) return false;
// In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
typeMembers = typeChecker.getPropertiesOfType(typeForObject);
existingMembers = (<ObjectBindingPattern>objectLikeContainer).elements;
else if (rootDeclaration.parent.kind === SyntaxKind.MethodDeclaration || rootDeclaration.parent.kind === SyntaxKind.SetAccessor) {
canGetType = isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(<Expression>rootDeclaration.parent.parent);
}
}
else {
Debug.fail("Root declaration is not variable-like.");
if (canGetType) {
const typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer);
if (!typeForObject) return false;
// In a binding pattern, get only known properties. Everywhere else we will get all possible properties.
typeMembers = typeChecker.getPropertiesOfType(typeForObject);
existingMembers = (<ObjectBindingPattern>objectLikeContainer).elements;
}
}
else {
Debug.fail("Expected object literal or binding pattern, got " + objectLikeContainer.kind);
}
if (typeMembers && typeMembers.length > 0) {
// Add filtered items to the completion list
@@ -1003,14 +998,14 @@ namespace ts.Completions {
* Returns the immediate owning object literal or binding pattern of a context token,
* on the condition that one exists and that the context implies completion should be given.
*/
function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | BindingPattern {
function tryGetObjectLikeCompletionContainer(contextToken: Node): ObjectLiteralExpression | ObjectBindingPattern {
if (contextToken) {
switch (contextToken.kind) {
case SyntaxKind.OpenBraceToken: // const x = { |
case SyntaxKind.CommaToken: // const x = { a: 0, |
const parent = contextToken.parent;
if (parent && (parent.kind === SyntaxKind.ObjectLiteralExpression || parent.kind === SyntaxKind.ObjectBindingPattern)) {
return <ObjectLiteralExpression | BindingPattern>parent;
if (isObjectLiteralExpression(parent) || isObjectBindingPattern(parent)) {
return parent;
}
break;
}
+12 -6
View File
@@ -1,17 +1,23 @@
/* @internal */
namespace ts.DocumentHighlights {
export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] {
export function getDocumentHighlights(program: Program, cancellationToken: CancellationToken, sourceFile: SourceFile, position: number, sourceFilesToSearch: SourceFile[]): DocumentHighlights[] | undefined {
const node = getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true);
return node && (getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile));
if (!node) return undefined;
if (isJsxOpeningElement(node.parent) && node.parent.tagName === node || isJsxClosingElement(node.parent)) {
// For a JSX element, just highlight the matching tag, not all references.
const { openingElement, closingElement } = node.parent.parent;
const highlightSpans = [openingElement, closingElement].map(({ tagName }) => getHighlightSpanForNode(tagName, sourceFile));
return [{ fileName: sourceFile.fileName, highlightSpans }];
}
return getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile);
}
function getHighlightSpanForNode(node: Node, sourceFile: SourceFile): HighlightSpan {
const start = node.getStart(sourceFile);
const end = node.getEnd();
return {
fileName: sourceFile.fileName,
textSpan: createTextSpanFromBounds(start, end),
textSpan: createTextSpanFromNode(node, sourceFile),
kind: HighlightSpanKind.none
};
}
+5 -9
View File
@@ -678,9 +678,7 @@ namespace ts.FindAllReferences.Core {
return parent ? scope.getSourceFile() : scope;
}
function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile, fullStart = false): number[] {
const start = fullStart ? container.getFullStart() : container.getStart(sourceFile);
const end = container.getEnd();
function getPossibleSymbolReferencePositions(sourceFile: SourceFile, symbolName: string, container: Node = sourceFile): number[] {
const positions: number[] = [];
/// TODO: Cache symbol existence for files to save text search
@@ -695,10 +693,10 @@ namespace ts.FindAllReferences.Core {
const sourceLength = text.length;
const symbolNameLength = symbolName.length;
let position = text.indexOf(symbolName, start);
let position = text.indexOf(symbolName, container.pos);
while (position >= 0) {
// If we are past the end, stop looking
if (position > end) break;
if (position > container.end) break;
// We found a match. Make sure it's not part of a larger word (i.e. the char
// before and after it have to be a non-identifier char).
@@ -759,8 +757,7 @@ namespace ts.FindAllReferences.Core {
}
function addReferencesForKeywordInFile(sourceFile: SourceFile, kind: SyntaxKind, searchText: string, references: Push<NodeEntry>): void {
// Want fullStart so we can find the symbol in JSDoc comments
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile, /*fullStart*/ true);
const possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile);
for (const position of possiblePositions) {
const referenceLocation = getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true);
if (referenceLocation.kind === kind) {
@@ -784,8 +781,7 @@ namespace ts.FindAllReferences.Core {
return;
}
const fullStart = state.options.findInComments || container.jsDoc !== undefined || forEach(search.symbol.declarations, d => d.kind === ts.SyntaxKind.JSDocTypedefTag);
for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container, fullStart)) {
for (const position of getPossibleSymbolReferencePositions(sourceFile, search.text, container)) {
getReferencesAtLocation(sourceFile, position, search, state);
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ namespace ts.NavigateTo {
for (const sourceFile of sourceFiles) {
cancellationToken.throwIfCancellationRequested();
if (excludeDtsFiles && fileExtensionIs(sourceFile.fileName, ".d.ts")) {
if (excludeDtsFiles && fileExtensionIs(sourceFile.fileName, Extension.Dts)) {
continue;
}
+38 -42
View File
@@ -37,7 +37,7 @@ namespace ts {
let ruleProvider: formatting.RulesProvider;
function createNode<TKind extends SyntaxKind>(kind: TKind, pos: number, end: number, parent?: Node): NodeObject | TokenObject<TKind> | IdentifierObject {
const node = kind >= SyntaxKind.FirstNode ? new NodeObject(kind, pos, end) :
const node = isNodeKind(kind) ? new NodeObject(kind, pos, end) :
kind === SyntaxKind.Identifier ? new IdentifierObject(SyntaxKind.Identifier, pos, end) :
new TokenObject(kind, pos, end);
node.parent = parent;
@@ -103,10 +103,10 @@ namespace ts {
return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd());
}
private addSyntheticNodes(nodes: Node[], pos: number, end: number, useJSDocScanner?: boolean): number {
private addSyntheticNodes(nodes: Node[], pos: number, end: number): number {
scanner.setTextPos(pos);
while (pos < end) {
const token = useJSDocScanner ? scanner.scanJSDocToken() : scanner.scan();
const token = scanner.scan();
Debug.assert(token !== SyntaxKind.EndOfFileToken); // Else it would infinitely loop
const textPos = scanner.getTextPos();
if (textPos <= end) {
@@ -136,54 +136,50 @@ namespace ts {
}
private createChildren(sourceFile?: SourceFileLike) {
if (this.kind === SyntaxKind.JSDocComment || isJSDocTag(this)) {
if (!isNodeKind(this.kind)) {
this._children = emptyArray;
return;
}
if (isJSDocCommentContainingNode(this)) {
/** Don't add trivia for "tokens" since this is in a comment. */
const children: Node[] = [];
this.forEachChild(child => { children.push(child); });
this._children = children;
return;
}
else if (this.kind >= SyntaxKind.FirstNode) {
const children: Node[] = [];
scanner.setText((sourceFile || this.getSourceFile()).text);
let pos = this.pos;
const useJSDocScanner = isJSDocNode(this);
const processNode = (node: Node) => {
const isJSDocTagNode = isJSDocNode(node);
if (!isJSDocTagNode && pos < node.pos) {
pos = this.addSyntheticNodes(children, pos, node.pos, useJSDocScanner);
}
children.push(node);
if (!isJSDocTagNode) {
pos = node.end;
}
};
const processNodes = (nodes: NodeArray<Node>) => {
if (pos < nodes.pos) {
pos = this.addSyntheticNodes(children, pos, nodes.pos, useJSDocScanner);
}
children.push(this.createSyntaxList(nodes));
pos = nodes.end;
};
// jsDocComments need to be the first children
if (this.jsDoc) {
for (const jsDocComment of this.jsDoc) {
processNode(jsDocComment);
}
const children: Node[] = [];
scanner.setText((sourceFile || this.getSourceFile()).text);
let pos = this.pos;
const processNode = (node: Node) => {
pos = this.addSyntheticNodes(children, pos, node.pos);
children.push(node);
pos = node.end;
};
const processNodes = (nodes: NodeArray<Node>) => {
if (pos < nodes.pos) {
pos = this.addSyntheticNodes(children, pos, nodes.pos);
}
// For syntactic classifications, all trivia are classcified together, including jsdoc comments.
// For that to work, the jsdoc comments should still be the leading trivia of the first child.
// Restoring the scanner position ensures that.
pos = this.pos;
forEachChild(this, processNode, processNodes);
if (pos < this.end) {
this.addSyntheticNodes(children, pos, this.end);
children.push(this.createSyntaxList(nodes));
pos = nodes.end;
};
// jsDocComments need to be the first children
if (this.jsDoc) {
for (const jsDocComment of this.jsDoc) {
processNode(jsDocComment);
}
scanner.setText(undefined);
this._children = children;
}
else {
this._children = emptyArray;
// For syntactic classifications, all trivia are classcified together, including jsdoc comments.
// For that to work, the jsdoc comments should still be the leading trivia of the first child.
// Restoring the scanner position ensures that.
pos = this.pos;
forEachChild(this, processNode, processNodes);
if (pos < this.end) {
this.addSyntheticNodes(children, pos, this.end);
}
scanner.setText(undefined);
this._children = children;
}
public getChildCount(sourceFile?: SourceFile): number {
+7 -3
View File
@@ -94,6 +94,10 @@ namespace ts {
else if (isNamespaceReference(node)) {
return SemanticMeaning.Namespace;
}
else if (isTypeParameterDeclaration(node.parent)) {
Debug.assert(isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName
return SemanticMeaning.Type;
}
else {
return SemanticMeaning.Value;
}
@@ -710,7 +714,7 @@ namespace ts {
}
}
export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node): Node {
export function findPrecedingToken(position: number, sourceFile: SourceFile, startNode?: Node, includeJsDoc?: boolean): Node {
return find(startNode || sourceFile);
function findRightmostToken(n: Node): Node {
@@ -741,7 +745,7 @@ namespace ts {
// NOTE: JsxText is a weird kind of node that can contain only whitespaces (since they are not counted as trivia).
// if this is the case - then we should assume that token in question is located in previous child.
if (position < child.end && (nodeHasTokens(child) || child.kind === SyntaxKind.JsxText)) {
const start = child.getStart(sourceFile);
const start = (includeJsDoc && child.jsDoc ? child.jsDoc[0] : child).getStart(sourceFile);
const lookInPreviousChild =
(start >= position) || // cursor in the leading trivia
(child.kind === SyntaxKind.JsxText && start === child.end); // whitespace only JsxText
@@ -758,7 +762,7 @@ namespace ts {
}
}
Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile);
Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || isJSDocCommentContainingNode(n));
// Here we know that none of child token nodes embrace the position,
// the only known case is when position is at the end of the file.
@@ -1,11 +1,58 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(47,1): error TS2322: Type '(x: number) => number[]' is not assignable to type '<T>(x: T) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(50,1): error TS2322: Type '(x: number) => string[]' is not assignable to type '<T>(x: T) => string[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(53,1): error TS2322: Type '(x: number) => void' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(56,1): error TS2322: Type '(x: string, y: number) => string' is not assignable to type '<T, U>(x: T, y: U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(59,1): error TS2322: Type '(x: (arg: string) => number) => string' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'string' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(62,1): error TS2322: Type '(x: (arg: Base) => Derived) => Base' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(65,1): error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(68,1): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(71,1): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(74,1): error TS2322: Type '(...x: Derived[]) => Derived' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
Type 'Derived' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(77,1): error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Base>(x: T, y: T) => T'.
Types of parameters 'y' and 'y' are incompatible.
Types of parameters 'arg2' and 'arg2' are incompatible.
Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
Property 'bing' is missing in type 'Base'.
Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
Property 'bar' is missing in type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(80,1): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Base[]>(x: Base[], y: T) => Derived[]'.
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type 'Derived2[]'.
Type 'Base[]' is not assignable to type 'Derived2[]'.
Type 'Base' is not assignable to type 'Derived2'.
Property 'baz' is missing in type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Derived[]>(x: Base[], y: T) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (1 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (14 errors) ====
// these are all permitted with the current rules, since we do not do contextual signature instantiation
class Base { foo: string; }
@@ -53,51 +100,111 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b: <T>(x: T) => T[];
a = b; // ok
b = a; // ok
~
!!! error TS2322: Type '(x: number) => number[]' is not assignable to type '<T>(x: T) => T[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b2: <T>(x: T) => string[];
a2 = b2; // ok
b2 = a2; // ok
~~
!!! error TS2322: Type '(x: number) => string[]' is not assignable to type '<T>(x: T) => string[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b3: <T>(x: T) => T;
a3 = b3; // ok
b3 = a3; // ok
~~
!!! error TS2322: Type '(x: number) => void' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b4: <T, U>(x: T, y: U) => T;
a4 = b4; // ok
b4 = a4; // ok
~~
!!! error TS2322: Type '(x: string, y: number) => string' is not assignable to type '<T, U>(x: T, y: U) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
var b5: <T, U>(x: (arg: T) => U) => T;
a5 = b5; // ok
b5 = a5; // ok
~~
!!! error TS2322: Type '(x: (arg: string) => number) => string' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'T'.
var b6: <T extends Base, U extends Derived>(x: (arg: T) => U) => T;
a6 = b6; // ok
b6 = a6; // ok
~~
!!! error TS2322: Type '(x: (arg: Base) => Derived) => Base' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b7: <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U;
a7 = b7; // ok
b7 = a7; // ok
~~
!!! error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b8: <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U;
a8 = b8; // ok
b8 = a8; // ok
~~
!!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b9: <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number }) => U) => (r: T) => U;
a9 = b9; // ok
b9 = a9; // ok
~~
!!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
!!! error TS2322: Property 'bing' is missing in type 'Base'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b10: <T extends Derived>(...x: T[]) => T;
a10 = b10; // ok
b10 = a10; // ok
~~~
!!! error TS2322: Type '(...x: Derived[]) => Derived' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
!!! error TS2322: Type 'Derived' is not assignable to type 'T'.
var b11: <T extends Base>(x: T, y: T) => T;
a11 = b11; // ok
b11 = a11; // ok
~~~
!!! error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Base>(x: T, y: T) => T'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
!!! error TS2322: Property 'bar' is missing in type 'Base'.
var b12: <T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>;
a12 = b12; // ok
b12 = a12; // ok
~~~
!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Base[]>(x: Base[], y: T) => Derived[]'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'.
!!! error TS2322: Property 'baz' is missing in type 'Base'.
var b13: <T extends Array<Derived>>(x: Array<Base>, y: T) => T;
a13 = b13; // ok
b13 = a13; // ok
~~~
!!! error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Derived[]>(x: Base[], y: T) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
var b14: <T>(x: { a: T; b: T }) => T;
a14 = b14; // ok
b14 = a14; // ok
~~~
!!! error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
var b15: <T>(x: T) => T[];
a15 = b15; // ok
b15 = a15; // ok
@@ -1,3 +1,10 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(45,9): error TS2322: Type '(x: number) => string[]' is not assignable to type '<T, U>(x: T) => U[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(49,9): error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type '<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(52,9): error TS2322: Type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U' is not assignable to type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived'.
Types of parameters 'y' and 'y' are incompatible.
Types of parameters 'arg2' and 'arg2' are incompatible.
@@ -5,14 +12,49 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Types of property 'foo' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(53,9): error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
Types of parameters 'y' and 'y' are incompatible.
Types of parameters 'arg2' and 'arg2' are incompatible.
Type 'Base' is not assignable to type '{ foo: number; }'.
Types of property 'foo' are incompatible.
Type 'string' is not assignable to type 'number'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(58,9): error TS2322: Type '(...x: Base[]) => Base' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(62,9): error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Derived>(x: T, y: T) => T'.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(66,9): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Derived2[]>(x: Base[], y: Base[]) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(69,9): error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(70,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(73,9): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'string' is not assignable to type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(74,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'string'.
Type 'Base' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(89,9): error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
Type 'string[]' is not assignable to type 'T[]'.
Type 'string' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(90,9): error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
Type 'T[]' is not assignable to type 'string[]'.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(95,9): error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
Type 'T[]' is not assignable to type 'string[]'.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(96,9): error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
Type 'string[]' is not assignable to type 'T[]'.
Type 'string' is not assignable to type 'T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts (2 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts (15 errors) ====
// These are mostly permitted with the current loose rules. All ok unless otherwise noted.
module Errors {
@@ -58,10 +100,19 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b2: <T, U>(x: T) => U[];
a2 = b2;
b2 = a2;
~~
!!! error TS2322: Type '(x: number) => string[]' is not assignable to type '<T, U>(x: T) => U[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b7: <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V;
a7 = b7;
b7 = a7;
~~
!!! error TS2322: Type '(x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type '<T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b8: <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U;
a8 = b8; // error, { foo: number } and Base are incompatible
@@ -75,32 +126,62 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
b8 = a8; // error, { foo: number } and Base are incompatible
~~
!!! error TS2322: Type '(x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type '<T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type '{ foo: number; }'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b10: <T extends Derived>(...x: T[]) => T;
a10 = b10;
b10 = a10;
~~~
!!! error TS2322: Type '(...x: Base[]) => Base' is not assignable to type '<T extends Derived>(...x: T[]) => T'.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b11: <T extends Derived>(x: T, y: T) => T;
a11 = b11;
b11 = a11;
~~~
!!! error TS2322: Type '(x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type '<T extends Derived>(x: T, y: T) => T'.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b12: <T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T;
a12 = b12;
b12 = a12;
~~~
!!! error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Derived2[]>(x: Base[], y: Base[]) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
var b15: <T>(x: { a: T; b: T }) => T;
a15 = b15;
~~~
!!! error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
b15 = a15;
~~~
!!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
var b15a: <T extends Base>(x: { a: T; b: T }) => number;
a15 = b15a;
~~~
!!! error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'Base'.
b15a = a15;
~~~~
!!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
!!! error TS2322: Type 'Base' is not assignable to type 'string'.
var b16: <T>(x: (a: T) => T) => T[];
a16 = b16;
@@ -116,12 +197,28 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var a2: <T>(x: T) => T[];
var b2: <T>(x: T) => string[];
a2 = b2;
~~
!!! error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'.
!!! error TS2322: Type 'string' is not assignable to type 'T'.
b2 = a2;
~~
!!! error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
// target type has generic call signature
var a3: <T>(x: T) => string[];
var b3: <T>(x: T) => T[];
a3 = b3;
~~
!!! error TS2322: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
b3 = a3;
~~
!!! error TS2322: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'.
!!! error TS2322: Type 'string' is not assignable to type 'T'.
}
}
@@ -0,0 +1,93 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(40,1): error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(55,1): error TS2322: Type '<T>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
Type '(U | V)[]' is not assignable to type 'U[]'.
Type 'U | V' is not assignable to type 'U'.
Type 'V' is not assignable to type 'U'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(58,1): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'U' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts (3 errors) ====
// checking assignment compat for function types. No errors in this file
class Base { foo: string; }
class Derived extends Base { bar: string; }
class Derived2 extends Derived { baz: string; }
class OtherDerived extends Base { bing: string; }
var a: <T>(x: T) => T[];
var a2: <T>(x: T) => string[];
var a3: <T>(x: T) => void;
var a4: <T,U>(x: T, y: U) => string;
var a5: <T,U>(x: (arg: T) => U) => T;
var a6: <T extends Base>(x: (arg: T) => Derived) => T;
var a11: <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
var a15: <T>(x: { a: T; b: T }) => T[];
var a16: <T extends Base>(x: { a: T; b: T }) => T[];
var a17: {
<T extends Derived>(x: (a: T) => T): T[];
<T extends Base>(x: (a: T) => T): T[];
};
var a18: {
(x: {
<T extends Derived>(a: T): T;
<T extends Base>(a: T): T;
}): any[];
(x: {
<T extends Derived2>(a: T): T;
<T extends Base>(a: T): T;
}): any[];
};
var b: <T>(x: T) => T[];
a = b; // ok
b = a; // ok
var b2: <T>(x: T) => string[];
a2 = b2; // ok
b2 = a2; // ok
var b3: <T>(x: T) => T;
a3 = b3; // ok
b3 = a3; // ok
~~
!!! error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Type 'void' is not assignable to type 'T'.
var b4: <T, U>(x: T, y: U) => string;
a4 = b4; // ok
b4 = a4; // ok
var b5: <T, U>(x: (arg: T) => U) => T;
a5 = b5; // ok
b5 = a5; // ok
var b6: <T extends Base, U extends Derived>(x: (arg: T) => U) => T;
a6 = b6; // ok
b6 = a6; // ok
var b11: <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
a11 = b11; // ok
b11 = a11; // ok
var b15: <U, V>(x: { a: U; b: V; }) => U[];
a15 = b15; // ok, T = U, T = V
b15 = a15; // ok
~~~
!!! error TS2322: Type '<T>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'.
!!! error TS2322: Type 'U | V' is not assignable to type 'U'.
!!! error TS2322: Type 'V' is not assignable to type 'U'.
var b16: <T>(x: { a: T; b: T }) => T[];
a15 = b16; // ok
b15 = a16; // ok
~~~
!!! error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type 'Base'.
var b17: <T>(x: (a: T) => T) => T[];
a17 = b17; // ok
b17 = a17; // ok
var b18: (x: <T>(a: T) => T) => any[];
a18 = b18; // ok
b18 = a18; // ok
@@ -0,0 +1,61 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(30,1): error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(42,1): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<T>(x: { a: T; b: T; }) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts (2 errors) ====
// checking assignment compatibility relations for function types. All valid
class Base { foo: string; }
class Derived extends Base { bar: string; }
class Derived2 extends Derived { baz: string; }
class OtherDerived extends Base { bing: string; }
interface A {
a: <T>(x: T) => T[];
a2: <T>(x: T) => string[];
a3: <T>(x: T) => void;
a4: <T,U>(x: T, y: U) => string;
a5: <T,U>(x: (arg: T) => U) => T;
a6: <T extends Base>(x: (arg: T) => Derived) => T;
a11: <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
a15: <T>(x: { a: T; b: T }) => T[];
a16: <T extends Base>(x: { a: T; b: T }) => T[];
}
var x: A;
var b: <T>(x: T) => T[];
x.a = b;
b = x.a;
var b2: <T>(x: T) => string[];
x.a2 = b2;
b2 = x.a2;
var b3: <T>(x: T) => T;
x.a3 = b3;
b3 = x.a3;
~~
!!! error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Type 'void' is not assignable to type 'T'.
var b4: <T, U>(x: T, y: U) => string;
x.a4 = b4;
b4 = x.a4;
var b5: <T, U>(x: (arg: T) => U) => T;
x.a5 = b5;
b5 = x.a5;
var b11: <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
x.a11 = b11;
b11 = x.a11;
var b16: <T>(x: { a: T; b: T }) => T[];
x.a16 = b16;
b16 = x.a16;
~~~
!!! error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<T>(x: { a: T; b: T; }) => T[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Base'.
@@ -1,11 +1,58 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(47,1): error TS2322: Type 'new (x: number) => number[]' is not assignable to type 'new <T>(x: T) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(50,1): error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(53,1): error TS2322: Type 'new (x: number) => void' is not assignable to type 'new <T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(56,1): error TS2322: Type 'new (x: string, y: number) => string' is not assignable to type 'new <T, U>(x: T, y: U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(59,1): error TS2322: Type 'new (x: (arg: string) => number) => string' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'string' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(62,1): error TS2322: Type 'new (x: (arg: Base) => Derived) => Base' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(65,1): error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(68,1): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(71,1): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(74,1): error TS2322: Type 'new (...x: Derived[]) => Derived' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
Type 'Derived' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(77,1): error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Base>(x: T, y: T) => T'.
Types of parameters 'y' and 'y' are incompatible.
Types of parameters 'arg2' and 'arg2' are incompatible.
Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
Property 'bing' is missing in type 'Base'.
Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
Property 'bar' is missing in type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(80,1): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Base[]>(x: Base[], y: T) => Derived[]'.
Types of parameters 'y' and 'y' are incompatible.
Type 'T' is not assignable to type 'Derived2[]'.
Type 'Base[]' is not assignable to type 'Derived2[]'.
Type 'Base' is not assignable to type 'Derived2'.
Property 'baz' is missing in type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Derived[]>(x: Base[], y: T) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (1 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (14 errors) ====
// checking assignment compatibility relations for function types. All of these are valid.
class Base { foo: string; }
@@ -53,51 +100,111 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b: new <T>(x: T) => T[];
a = b; // ok
b = a; // ok
~
!!! error TS2322: Type 'new (x: number) => number[]' is not assignable to type 'new <T>(x: T) => T[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b2: new <T>(x: T) => string[];
a2 = b2; // ok
b2 = a2; // ok
~~
!!! error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b3: new <T>(x: T) => T;
a3 = b3; // ok
b3 = a3; // ok
~~
!!! error TS2322: Type 'new (x: number) => void' is not assignable to type 'new <T>(x: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b4: new <T, U>(x: T, y: U) => T;
a4 = b4; // ok
b4 = a4; // ok
~~
!!! error TS2322: Type 'new (x: string, y: number) => string' is not assignable to type 'new <T, U>(x: T, y: U) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
var b5: new <T, U>(x: (arg: T) => U) => T;
a5 = b5; // ok
b5 = a5; // ok
~~
!!! error TS2322: Type 'new (x: (arg: string) => number) => string' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'T'.
var b6: new <T extends Base, U extends Derived>(x: (arg: T) => U) => T;
a6 = b6; // ok
b6 = a6; // ok
~~
!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => Base' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b7: new <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U;
a7 = b7; // ok
b7 = a7; // ok
~~
!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b8: new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U;
a8 = b8; // ok
b8 = a8; // ok
~~
!!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: T) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b9: new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number }) => U) => (r: T) => U;
a9 = b9; // ok
b9 = a9; // ok
~~
!!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: string; bing: number; }) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bing: number; }'.
!!! error TS2322: Property 'bing' is missing in type 'Base'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b10: new <T extends Derived>(...x: T[]) => T;
a10 = b10; // ok
b10 = a10; // ok
~~~
!!! error TS2322: Type 'new (...x: Derived[]) => Derived' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
!!! error TS2322: Type 'Derived' is not assignable to type 'T'.
var b11: new <T extends Base>(x: T, y: T) => T;
a11 = b11; // ok
b11 = a11; // ok
~~~
!!! error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Base>(x: T, y: T) => T'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type '{ foo: string; bar: string; }'.
!!! error TS2322: Type 'Base' is not assignable to type '{ foo: string; bar: string; }'.
!!! error TS2322: Property 'bar' is missing in type 'Base'.
var b12: new <T extends Array<Base>>(x: Array<Base>, y: T) => Array<Derived>;
a12 = b12; // ok
b12 = a12; // ok
~~~
!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Base[]>(x: Base[], y: T) => Derived[]'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base[]' is not assignable to type 'Derived2[]'.
!!! error TS2322: Type 'Base' is not assignable to type 'Derived2'.
!!! error TS2322: Property 'baz' is missing in type 'Base'.
var b13: new <T extends Array<Derived>>(x: Array<Base>, y: T) => T;
a13 = b13; // ok
b13 = a13; // ok
~~~
!!! error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Derived[]>(x: Base[], y: T) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
var b14: new <T>(x: { a: T; b: T }) => T;
a14 = b14; // ok
b14 = a14; // ok
~~~
!!! error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
var b15: new <T>(x: T) => T[];
a15 = b15; // ok
b15 = a15; // ok
@@ -1,3 +1,10 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(45,9): error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T, U>(x: T) => U[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(49,9): error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type 'new <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(52,9): error TS2322: Type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U' is not assignable to type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived'.
Types of parameters 'y' and 'y' are incompatible.
Types of parameters 'arg2' and 'arg2' are incompatible.
@@ -5,11 +12,34 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Types of property 'foo' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(53,9): error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
Types of parameters 'y' and 'y' are incompatible.
Types of parameters 'arg2' and 'arg2' are incompatible.
Type 'Base' is not assignable to type '{ foo: number; }'.
Types of property 'foo' are incompatible.
Type 'string' is not assignable to type 'number'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(58,9): error TS2322: Type 'new (...x: Base[]) => Base' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(62,9): error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Derived>(x: T, y: T) => T'.
Type 'Base' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(66,9): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Derived2[]>(x: Base[], y: Base[]) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(69,9): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(70,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(73,9): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'string' is not assignable to type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(74,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'string'.
Type 'Base' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(77,9): error TS2322: Type 'new <T>(x: (a: T) => T) => T[]' is not assignable to type '{ new (x: { new (a: number): number; new (a?: number): number; }): number[]; new (x: { new (a: boolean): boolean; new (a?: boolean): boolean; }): boolean[]; }'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ new (a: number): number; new (a?: number): number; }' is not assignable to type '(a: any) => any'.
@@ -26,9 +56,21 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Types of parameters 'x' and 'x' are incompatible.
Type '(a: any) => any' is not assignable to type '{ new <T extends Derived>(a: T): T; new <T extends Base>(a: T): T; }'.
Type '(a: any) => any' provides no match for the signature 'new <T extends Derived>(a: T): T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(89,9): error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
Type 'string[]' is not assignable to type 'T[]'.
Type 'string' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(90,9): error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
Type 'T[]' is not assignable to type 'string[]'.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(95,9): error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
Type 'T[]' is not assignable to type 'string[]'.
Type 'T' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(96,9): error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
Type 'string[]' is not assignable to type 'T[]'.
Type 'string' is not assignable to type 'T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts (6 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts (19 errors) ====
// checking assignment compatibility relations for function types.
module Errors {
@@ -74,10 +116,19 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b2: new <T, U>(x: T) => U[];
a2 = b2; // ok
b2 = a2; // ok
~~
!!! error TS2322: Type 'new (x: number) => string[]' is not assignable to type 'new <T, U>(x: T) => U[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'number'.
var b7: new <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V;
a7 = b7; // ok
b7 = a7; // ok
~~
!!! error TS2322: Type 'new (x: (arg: Base) => Derived) => (r: Base) => Derived2' is not assignable to type 'new <T extends Base, U extends Derived, V extends Derived2>(x: (arg: T) => U) => (r: T) => V'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b8: new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U;
a8 = b8; // error, type mismatch
@@ -91,32 +142,62 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
b8 = a8; // error
~~
!!! error TS2322: Type 'new (x: (arg: Base) => Derived, y: (arg2: Base) => Derived) => (r: Base) => Derived' is not assignable to type 'new <T extends Base, U extends Derived>(x: (arg: T) => U, y: (arg2: { foo: number; }) => U) => (r: T) => U'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Types of parameters 'arg2' and 'arg2' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type '{ foo: number; }'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b10: new <T extends Derived>(...x: T[]) => T;
a10 = b10; // ok
b10 = a10; // ok
~~~
!!! error TS2322: Type 'new (...x: Base[]) => Base' is not assignable to type 'new <T extends Derived>(...x: T[]) => T'.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b11: new <T extends Derived>(x: T, y: T) => T;
a11 = b11; // ok
b11 = a11; // ok
~~~
!!! error TS2322: Type 'new (x: { foo: string; }, y: { foo: string; bar: string; }) => Base' is not assignable to type 'new <T extends Derived>(x: T, y: T) => T'.
!!! error TS2322: Type 'Base' is not assignable to type 'T'.
var b12: new <T extends Array<Derived2>>(x: Array<Base>, y: Array<Base>) => T;
a12 = b12; // ok
b12 = a12; // ok
~~~
!!! error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Derived2[]>(x: Base[], y: Base[]) => T'.
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
var b15: new <T>(x: { a: T; b: T }) => T;
a15 = b15; // ok
~~~
!!! error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
b15 = a15; // ok
~~~
!!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
var b15a: new <T extends Base>(x: { a: T; b: T }) => number;
a15 = b15a; // ok
~~~
!!! error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'Base'.
b15a = a15; // ok
~~~~
!!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
!!! error TS2322: Type 'Base' is not assignable to type 'string'.
var b16: new <T>(x: (a: T) => T) => T[];
a16 = b16; // error
@@ -152,12 +233,28 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var a2: new <T>(x: T) => T[];
var b2: new <T>(x: T) => string[];
a2 = b2; // ok
~~
!!! error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'.
!!! error TS2322: Type 'string' is not assignable to type 'T'.
b2 = a2; // ok
~~
!!! error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
// target type has generic call signature
var a3: new <T>(x: T) => string[];
var b3: new <T>(x: T) => T[];
a3 = b3; // ok
~~
!!! error TS2322: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
!!! error TS2322: Type 'T[]' is not assignable to type 'string[]'.
!!! error TS2322: Type 'T' is not assignable to type 'string'.
b3 = a3; // ok
~~
!!! error TS2322: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
!!! error TS2322: Type 'string[]' is not assignable to type 'T[]'.
!!! error TS2322: Type 'string' is not assignable to type 'T'.
}
}
@@ -0,0 +1,93 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(40,1): error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(55,1): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
Type '(U | V)[]' is not assignable to type 'U[]'.
Type 'U | V' is not assignable to type 'U'.
Type 'V' is not assignable to type 'U'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(58,1): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'U' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts (3 errors) ====
// checking assignment compat for function types. All valid
class Base { foo: string; }
class Derived extends Base { bar: string; }
class Derived2 extends Derived { baz: string; }
class OtherDerived extends Base { bing: string; }
var a: new <T>(x: T) => T[];
var a2: new <T>(x: T) => string[];
var a3: new <T>(x: T) => void;
var a4: new <T, U>(x: T, y: U) => string;
var a5: new <T, U>(x: new (arg: T) => U) => T;
var a6: new <T extends Base>(x: new (arg: T) => Derived) => T;
var a11: new <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
var a15: new <T>(x: { a: T; b: T }) => T[];
var a16: new <T extends Base>(x: { a: T; b: T }) => T[];
var a17: {
new <T extends Derived>(x: new (a: T) => T): T[];
new <T extends Base>(x: new (a: T) => T): T[];
};
var a18: {
new (x: {
new <T extends Derived>(a: T): T;
new <T extends Base>(a: T): T;
}): any[];
new (x: {
new <T extends Derived2>(a: T): T;
new <T extends Base>(a: T): T;
}): any[];
};
var b: new <T>(x: T) => T[];
a = b; // ok
b = a; // ok
var b2: new <T>(x: T) => string[];
a2 = b2; // ok
b2 = a2; // ok
var b3: new <T>(x: T) => T;
a3 = b3; // ok
b3 = a3; // ok
~~
!!! error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
!!! error TS2322: Type 'void' is not assignable to type 'T'.
var b4: new <T, U>(x: T, y: U) => string;
a4 = b4; // ok
b4 = a4; // ok
var b5: new <T, U>(x: new (arg: T) => U) => T;
a5 = b5; // ok
b5 = a5; // ok
var b6: new <T extends Base, U extends Derived>(x: new (arg: T) => U) => T;
a6 = b6; // ok
b6 = a6; // ok
var b11: new <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
a11 = b11; // ok
b11 = a11; // ok
var b15: new <U, V>(x: { a: U; b: V; }) => U[];
a15 = b15; // ok
b15 = a15; // ok
~~~
!!! error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'.
!!! error TS2322: Type 'U | V' is not assignable to type 'U'.
!!! error TS2322: Type 'V' is not assignable to type 'U'.
var b16: new <T>(x: { a: T; b: T }) => T[];
a15 = b16; // ok
b15 = a16; // ok
~~~
!!! error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type 'Base'.
var b17: new <T>(x: new (a: T) => T) => T[];
a17 = b17; // ok
b17 = a17; // ok
var b18: new (x: new <T>(a: T) => T) => any[];
a18 = b18; // ok
b18 = a18; // ok
@@ -0,0 +1,61 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(30,1): error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(42,1): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts (2 errors) ====
// checking assignment compatibility relations for function types. All valid.
class Base { foo: string; }
class Derived extends Base { bar: string; }
class Derived2 extends Derived { baz: string; }
class OtherDerived extends Base { bing: string; }
interface A {
a: new <T>(x: T) => T[];
a2: new <T>(x: T) => string[];
a3: new <T>(x: T) => void;
a4: new <T, U>(x: T, y: U) => string;
a5: new <T, U>(x: (arg: T) => U) => T;
a6: new <T extends Base>(x: (arg: T) => Derived) => T;
a11: new <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
a15: new <T>(x: { a: T; b: T }) => T[];
a16: new <T extends Base>(x: { a: T; b: T }) => T[];
}
var x: A;
var b: new <T>(x: T) => T[];
x.a = b;
b = x.a;
var b2: new <T>(x: T) => string[];
x.a2 = b2;
b2 = x.a2;
var b3: new <T>(x: T) => T;
x.a3 = b3;
b3 = x.a3;
~~
!!! error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
!!! error TS2322: Type 'void' is not assignable to type 'T'.
var b4: new <T, U>(x: T, y: U) => string;
x.a4 = b4;
b4 = x.a4;
var b5: new <T, U>(x: (arg: T) => U) => T;
x.a5 = b5;
b5 = x.a5;
var b11: new <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
x.a11 = b11;
b11 = x.a11;
var b16: new <T>(x: { a: T; b: T }) => T[];
x.a16 = b16;
b16 = x.a16;
~~~
!!! error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T[]'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2322: Types of property 'a' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'Base'.
@@ -0,0 +1,27 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts(16,1): error TS2322: Type 'A' is not assignable to type 'B'.
Types of parameters 'y' and 'y' are incompatible.
Type 'S' is not assignable to type 'S[]'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts (1 errors) ====
// some complex cases of assignment compat of generic signatures. No contextual signature instantiation
interface A {
<T>(x: T, ...y: T[][]): void
}
interface B {
<S>(x: S, ...y: S[]): void
}
var a: A;
var b: B;
// Both ok
a = b;
b = a;
~
!!! error TS2322: Type 'A' is not assignable to type 'B'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'S' is not assignable to type 'S[]'.
@@ -0,0 +1,27 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures4.ts(12,1): error TS2322: Type '<T extends I2<T>>(z: T) => void' is not assignable to type '<T extends I2<I2<T>>>(z: T) => void'.
Types of parameters 'z' and 'z' are incompatible.
Type 'T' is not assignable to type 'I2<T>'.
Type 'I2<I2<T>>' is not assignable to type 'I2<T>'.
Type 'I2<T>' is not assignable to type 'T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures4.ts (1 errors) ====
// some complex cases of assignment compat of generic signatures.
interface I2<T> {
p: T
}
var x: <T extends I2<T>>(z: T) => void
var y: <T extends I2<I2<T>>>(z: T) => void
// These both do not make sense as we would eventually be comparing I2<T> to I2<I2<T>>, and they are self referencing anyway
x = y
y = x
~
!!! error TS2322: Type '<T extends I2<T>>(z: T) => void' is not assignable to type '<T extends I2<I2<T>>>(z: T) => void'.
!!! error TS2322: Types of parameters 'z' and 'z' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'I2<T>'.
!!! error TS2322: Type 'I2<I2<T>>' is not assignable to type 'I2<T>'.
!!! error TS2322: Type 'I2<T>' is not assignable to type 'T'.
@@ -1,12 +1,74 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(14,13): error TS2322: Type '(x: T) => any' is not assignable to type '() => T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(23,13): error TS2322: Type '(x: T, y: T) => any' is not assignable to type '(x: T) => T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(63,9): error TS2322: Type '() => T' is not assignable to type '<T>() => T'.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(64,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>() => T'.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(65,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>() => T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(66,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>() => T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(67,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>() => T'.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(69,9): error TS2322: Type '() => T' is not assignable to type '<T>(x?: T) => T'.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(70,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(71,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(72,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(73,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(75,9): error TS2322: Type '() => T' is not assignable to type '<T>(x: T) => T'.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(76,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(77,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(78,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(79,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(81,9): error TS2322: Type '() => T' is not assignable to type '<T>(x: T, y?: T) => T'.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(82,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(83,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(84,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(85,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(87,9): error TS2322: Type '() => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(88,9): error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(89,9): error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(90,9): error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(91,9): error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(107,13): error TS2322: Type '<T>(x: T) => any' is not assignable to type '<T>() => T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts(116,13): error TS2322: Type '<T>(x: T, y: T) => any' is not assignable to type '<T>(x: T) => T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts (6 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignaturesWithOptionalParameters.ts (29 errors) ====
// call signatures in derived types must have the same or fewer optional parameters as the target for assignment
module ClassTypeParam {
@@ -74,7 +136,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
// all errors
b.a = t.a;
~~~
!!! error TS2322: Type '() => T' is not assignable to type '<T>() => T'.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a = t.a2;
~~~
!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>() => T'.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a = t.a3;
~~~
!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>() => T'.
@@ -82,30 +150,109 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
~~~
!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>() => T'.
b.a = t.a5;
~~~
!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>() => T'.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a2 = t.a;
~~~~
!!! error TS2322: Type '() => T' is not assignable to type '<T>(x?: T) => T'.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a2 = t.a2;
~~~~
!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a2 = t.a3;
~~~~
!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a2 = t.a4;
~~~~
!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a2 = t.a5;
~~~~
!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a3 = t.a;
~~~~
!!! error TS2322: Type '() => T' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a3 = t.a2;
~~~~
!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a3 = t.a3;
~~~~
!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a3 = t.a4;
~~~~
!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a3 = t.a5;
~~~~
!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a4 = t.a;
~~~~
!!! error TS2322: Type '() => T' is not assignable to type '<T>(x: T, y?: T) => T'.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a4 = t.a2;
~~~~
!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a4 = t.a3;
~~~~
!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a4 = t.a4;
~~~~
!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a4 = t.a5;
~~~~
!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a5 = t.a;
~~~~
!!! error TS2322: Type '() => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a5 = t.a2;
~~~~
!!! error TS2322: Type '(x?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a5 = t.a3;
~~~~
!!! error TS2322: Type '(x: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a5 = t.a4;
~~~~
!!! error TS2322: Type '(x: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
b.a5 = t.a5;
~~~~
!!! error TS2322: Type '(x?: T, y?: T) => T' is not assignable to type '<T>(x?: T, y?: T) => T'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
}
}
@@ -0,0 +1,19 @@
tests/cases/compiler/assignmentStricterConstraints.ts(7,1): error TS2322: Type '<T, S extends T>(x: T, y: S) => void' is not assignable to type '<T, S>(x: T, y: S) => void'.
Types of parameters 'y' and 'y' are incompatible.
Type 'S' is not assignable to type 'T'.
==== tests/cases/compiler/assignmentStricterConstraints.ts (1 errors) ====
var f = function <T, S extends T>(x: T, y: S): void {
x = y
}
var g = function <T, S>(x: T, y: S): void { }
g = f
~
!!! error TS2322: Type '<T, S extends T>(x: T, y: S) => void' is not assignable to type '<T, S>(x: T, y: S) => void'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'S' is not assignable to type 'T'.
g(1, "")
@@ -4,10 +4,10 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(9,23): error TS1055: Type 'PromiseLike' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(10,23): error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
Type 'Thenable' is not assignable to type 'PromiseLike<any>'.
Type 'Thenable' is not assignable to type 'PromiseLike<T>'.
Types of property 'then' are incompatible.
Type '() => void' is not assignable to type '<TResult1 = any, TResult2 = never>(onfulfilled?: (value: any) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
Type 'void' is not assignable to type 'PromiseLike<any>'.
Type '() => void' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(17,16): error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration15_es5.ts(23,25): error TS1320: Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.
@@ -35,10 +35,10 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
!!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
~~~~~~~~
!!! error TS1055: Type 'typeof Thenable' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.
!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike<any>'.
!!! error TS1055: Type 'Thenable' is not assignable to type 'PromiseLike<T>'.
!!! error TS1055: Types of property 'then' are incompatible.
!!! error TS1055: Type '() => void' is not assignable to type '<TResult1 = any, TResult2 = never>(onfulfilled?: (value: any) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike<any>'.
!!! error TS1055: Type '() => void' is not assignable to type '<TResult1 = T, TResult2 = never>(onfulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<TResult1 | TResult2>'.
!!! error TS1055: Type 'void' is not assignable to type 'PromiseLike<TResult1 | TResult2>'.
async function fn7() { return; } // valid: Promise<void>
async function fn8() { return 1; } // valid: Promise<number>
async function fn9() { return null; } // valid: Promise<any>
@@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
Types of property 'a' are incompatible.
Type '(x: number) => string' is not assignable to type '(x: number) => number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts(63,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
Types of property 'a2' are incompatible.
Type '<T>(x: T) => string' is not assignable to type '<T>(x: T) => T'.
Type 'string' is not assignable to type 'T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts (1 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance.ts (2 errors) ====
module CallSignature {
interface Base { // T
// M's
@@ -73,6 +77,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
// S's
interface I3 extends Base2 {
~~
!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type '<T>(x: T) => string' is not assignable to type '<T>(x: T) => T'.
!!! error TS2430: Type 'string' is not assignable to type 'T'.
// N's
a2: <T>(x: T) => string; // error because base returns non-void;
}
@@ -11,9 +11,31 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
Type '{ foo: number; }' is not assignable to type 'Base'.
Types of property 'foo' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(76,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'.
Types of property 'a15' are incompatible.
Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(80,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'.
Types of property 'a15' are incompatible.
Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'string' is not assignable to type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(100,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'.
Types of property 'a2' are incompatible.
Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
Type 'string[]' is not assignable to type 'T[]'.
Type 'string' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts(109,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'.
Types of property 'a2' are incompatible.
Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
Type 'T[]' is not assignable to type 'string[]'.
Type 'T' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts (2 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance3.ts (6 errors) ====
// checking subtype relations for function types as it relates to contextual signature instantiation
// error cases
@@ -105,10 +127,24 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
}
interface I6 extends A {
~~
!!! error TS2430: Interface 'I6' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a15' are incompatible.
!!! error TS2430: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
!!! error TS2430: Type 'string | number' is not assignable to type 'number'.
!!! error TS2430: Type 'string' is not assignable to type 'number'.
a15: <T>(x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type
}
interface I7 extends A {
~~
!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a15' are incompatible.
!!! error TS2430: Type '<T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type '(x: { a: string; b: number; }) => number'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2430: Types of property 'a' are incompatible.
!!! error TS2430: Type 'string' is not assignable to type 'Base'.
a15: <T extends Base>(x: { a: T; b: T }) => number; // error, T defaults to Base, which is not compatible with number or string
}
@@ -129,6 +165,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
}
interface I6 extends B {
~~
!!! error TS2430: Interface 'I6' incorrectly extends interface 'B'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type '<T>(x: T) => string[]' is not assignable to type '<T>(x: T) => T[]'.
!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'.
!!! error TS2430: Type 'string' is not assignable to type 'T'.
a2: <T>(x: T) => string[]; // error
}
@@ -138,6 +180,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
}
interface I7 extends C {
~~
!!! error TS2430: Interface 'I7' incorrectly extends interface 'C'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type '<T>(x: T) => T[]' is not assignable to type '<T>(x: T) => string[]'.
!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'.
!!! error TS2430: Type 'T' is not assignable to type 'string'.
a2: <T>(x: T) => T[]; // error
}
}
@@ -0,0 +1,142 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(24,11): error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
Types of property 'a' are incompatible.
Type '(x: T) => T[]' is not assignable to type '<T>(x: T) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(28,11): error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
Types of property 'a2' are incompatible.
Type '(x: T) => string[]' is not assignable to type '<T>(x: T) => string[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(32,11): error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
Types of property 'a3' are incompatible.
Type '(x: T) => T' is not assignable to type '<T>(x: T) => void'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(36,11): error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
Types of property 'a4' are incompatible.
Type '<U>(x: T, y: U) => string' is not assignable to type '<T, U>(x: T, y: U) => string'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(40,11): error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
Types of property 'a5' are incompatible.
Type '<U>(x: (arg: T) => U) => T' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(44,11): error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
Types of property 'a11' are incompatible.
Type '<U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
Types of property 'foo' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts(48,11): error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
Types of property 'a16' are incompatible.
Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
Type 'Base' is not assignable to type 'T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts (7 errors) ====
// checking subtype relations for function types as it relates to contextual signature instantiation
// same as subtypingWithCallSignatures4 but using class type parameters instead of generic signatures
// all are errors
class Base { foo: string; }
class Derived extends Base { bar: string; }
class Derived2 extends Derived { baz: string; }
class OtherDerived extends Base { bing: string; }
interface A { // T
// M's
a: <T>(x: T) => T[];
a2: <T>(x: T) => string[];
a3: <T>(x: T) => void;
a4: <T,U>(x: T, y: U) => string;
a5: <T,U>(x: (arg: T) => U) => T;
a6: <T extends Base>(x: (arg: T) => Derived) => T;
a11: <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
a15: <T>(x: { a: T; b: T }) => T[];
a16: <T extends Base>(x: { a: T; b: T }) => T[];
}
// S's
interface I<T> extends A {
~
!!! error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a' are incompatible.
!!! error TS2430: Type '(x: T) => T[]' is not assignable to type '<T>(x: T) => T[]'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a: (x: T) => T[];
}
interface I2<T> extends A {
~~
!!! error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type '(x: T) => string[]' is not assignable to type '<T>(x: T) => string[]'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a2: (x: T) => string[];
}
interface I3<T> extends A {
~~
!!! error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a3' are incompatible.
!!! error TS2430: Type '(x: T) => T' is not assignable to type '<T>(x: T) => void'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a3: (x: T) => T;
}
interface I4<T> extends A {
~~
!!! error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a4' are incompatible.
!!! error TS2430: Type '<U>(x: T, y: U) => string' is not assignable to type '<T, U>(x: T, y: U) => string'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a4: <U>(x: T, y: U) => string;
}
interface I5<T> extends A {
~~
!!! error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a5' are incompatible.
!!! error TS2430: Type '<U>(x: (arg: T) => U) => T' is not assignable to type '<T, U>(x: (arg: T) => U) => T'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a5: <U>(x: (arg: T) => U) => T;
}
interface I7<T> extends A {
~~
!!! error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a11' are incompatible.
!!! error TS2430: Type '<U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
!!! error TS2430: Types of property 'foo' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a11: <U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
}
interface I9<T> extends A {
~~
!!! error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a16' are incompatible.
!!! error TS2430: Type '(x: { a: T; b: T; }) => T[]' is not assignable to type '<T extends Base>(x: { a: T; b: T; }) => T[]'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
!!! error TS2430: Types of property 'a' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
!!! error TS2430: Type 'Base' is not assignable to type 'T'.
a16: (x: { a: T; b: T }) => T[];
}
@@ -0,0 +1,25 @@
tests/cases/conformance/jsdoc/returns.js(6,5): error TS2322: Type '5' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/returns.js(13,5): error TS2322: Type 'true | 5' is not assignable to type 'string | number'.
Type 'true' is not assignable to type 'string | number'.
==== tests/cases/conformance/jsdoc/returns.js (2 errors) ====
// @ts-check
/**
* @returns {string} This comment is not currently exposed
*/
function f() {
return 5;
~~~~~~~~~
!!! error TS2322: Type '5' is not assignable to type 'string'.
}
/**
* @returns {string | number} This comment is not currently exposed
*/
function f1() {
return 5 || true;
~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'true | 5' is not assignable to type 'string | number'.
!!! error TS2322: Type 'true' is not assignable to type 'string | number'.
}
@@ -61,10 +61,10 @@ x(1);
/** @type {function (number)} */
const x1 = (a) => a + 1;
>x1 : (arg0: number) => any
>(a) => a + 1 : (a: any) => any
>a : any
>a + 1 : any
>a : any
>(a) => a + 1 : (a: number) => number
>a : number
>a + 1 : number
>a : number
>1 : 1
x1(0);
@@ -75,10 +75,10 @@ x1(0);
/** @type {function (number): number} */
const x2 = (a) => a + 1;
>x2 : (arg0: number) => number
>(a) => a + 1 : (a: any) => any
>a : any
>a + 1 : any
>a : any
>(a) => a + 1 : (a: number) => number
>a : number
>a + 1 : number
>a : number
>1 : 1
x2(0);
@@ -1,9 +1,10 @@
tests/cases/conformance/jsdoc/0.js(3,5): error TS2322: Type 'true' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/0.js(6,5): error TS2322: Type '"hello"' is not assignable to type 'number'.
tests/cases/conformance/jsdoc/0.js(10,4): error TS2345: Argument of type '"string"' is not assignable to parameter of type 'number'.
tests/cases/conformance/jsdoc/0.js(13,7): error TS2451: Cannot redeclare block-scoped variable 'x2'.
tests/cases/conformance/jsdoc/0.js(17,1): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-scoped variable 'x2'.
tests/cases/conformance/jsdoc/0.js(20,21): error TS2339: Property 'concat' does not exist on type 'number'.
tests/cases/conformance/jsdoc/0.js(24,7): error TS2322: Type '(a: number) => number' is not assignable to type '(arg0: number) => string'.
Type 'number' is not assignable to type 'string'.
==== tests/cases/conformance/jsdoc/0.js (6 errors) ====
@@ -26,8 +27,6 @@ tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-s
/** @type {function (number): number} */
const x2 = (a) => a + 1;
~~
!!! error TS2451: Cannot redeclare block-scoped variable 'x2'.
/** @type {string} */
var a;
@@ -36,7 +35,14 @@ tests/cases/conformance/jsdoc/0.js(20,7): error TS2451: Cannot redeclare block-s
!!! error TS2322: Type 'number' is not assignable to type 'string'.
/** @type {function (number): number} */
const x2 = (a) => a.concat("hi");
const x3 = (a) => a.concat("hi");
~~~~~~
!!! error TS2339: Property 'concat' does not exist on type 'number'.
x3(0);
/** @type {function (number): string} */
const x4 = (a) => a + 1;
~~
!!! error TS2451: Cannot redeclare block-scoped variable 'x2'.
x2(0);
!!! error TS2322: Type '(a: number) => number' is not assignable to type '(arg0: number) => string'.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
x4(0);
@@ -18,8 +18,12 @@ var a;
a = x2(0);
/** @type {function (number): number} */
const x2 = (a) => a.concat("hi");
x2(0);
const x3 = (a) => a.concat("hi");
x3(0);
/** @type {function (number): string} */
const x4 = (a) => a + 1;
x4(0);
//// [0.js]
// @ts-check
@@ -36,5 +40,8 @@ var x2 = function (a) { return a + 1; };
var a;
a = x2(0);
/** @type {function (number): number} */
var x2 = function (a) { return a.concat("hi"); };
x2(0);
var x3 = function (a) { return a.concat("hi"); };
x3(0);
/** @type {function (number): string} */
var x4 = function (a) { return a + 1; };
x4(0);
@@ -2,9 +2,13 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
Types of property 'a' are incompatible.
Type 'new (x: number) => string' is not assignable to type 'new (x: number) => number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts(67,15): error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
Types of property 'a2' are incompatible.
Type 'new <T>(x: T) => string' is not assignable to type 'new <T>(x: T) => T'.
Type 'string' is not assignable to type 'T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts (1 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance.ts (2 errors) ====
// Checking basic subtype relations with construct signatures
module ConstructSignature {
@@ -77,6 +81,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
// S's
interface I3 extends Base2 {
~~
!!! error TS2430: Interface 'I3' incorrectly extends interface 'Base2'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type 'new <T>(x: T) => string' is not assignable to type 'new <T>(x: T) => T'.
!!! error TS2430: Type 'string' is not assignable to type 'T'.
// N's
a2: new <T>(x: T) => string; // error because base returns non-void;
}
@@ -11,9 +11,31 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
Type '{ foo: number; }' is not assignable to type 'Base'.
Types of property 'foo' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(66,19): error TS2430: Interface 'I6' incorrectly extends interface 'A'.
Types of property 'a15' are incompatible.
Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(70,19): error TS2430: Interface 'I7' incorrectly extends interface 'A'.
Types of property 'a15' are incompatible.
Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
Types of property 'a' are incompatible.
Type 'string' is not assignable to type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(86,19): error TS2430: Interface 'I6' incorrectly extends interface 'B'.
Types of property 'a2' are incompatible.
Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
Type 'string[]' is not assignable to type 'T[]'.
Type 'string' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts(95,19): error TS2430: Interface 'I7' incorrectly extends interface 'C'.
Types of property 'a2' are incompatible.
Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
Type 'T[]' is not assignable to type 'string[]'.
Type 'T' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts (2 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance3.ts (6 errors) ====
// checking subtype relations for function types as it relates to contextual signature instantiation
// error cases
@@ -95,10 +117,24 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
}
interface I6 extends A {
~~
!!! error TS2430: Interface 'I6' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a15' are incompatible.
!!! error TS2430: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
!!! error TS2430: Type 'string | number' is not assignable to type 'number'.
!!! error TS2430: Type 'string' is not assignable to type 'number'.
a15: new <T>(x: { a: T; b: T }) => T; // error, T is {} which isn't an acceptable return type
}
interface I7 extends A {
~~
!!! error TS2430: Interface 'I7' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a15' are incompatible.
!!! error TS2430: Type 'new <T extends Base>(x: { a: T; b: T; }) => number' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type '{ a: string; b: number; }' is not assignable to type '{ a: Base; b: Base; }'.
!!! error TS2430: Types of property 'a' are incompatible.
!!! error TS2430: Type 'string' is not assignable to type 'Base'.
a15: new <T extends Base>(x: { a: T; b: T }) => number; // error, T defaults to Base, which is not compatible with number or string
}
@@ -115,6 +151,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
}
interface I6 extends B {
~~
!!! error TS2430: Interface 'I6' incorrectly extends interface 'B'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type 'new <T>(x: T) => string[]' is not assignable to type 'new <T>(x: T) => T[]'.
!!! error TS2430: Type 'string[]' is not assignable to type 'T[]'.
!!! error TS2430: Type 'string' is not assignable to type 'T'.
a2: new <T>(x: T) => string[]; // error
}
@@ -124,6 +166,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
}
interface I7 extends C {
~~
!!! error TS2430: Interface 'I7' incorrectly extends interface 'C'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type 'new <T>(x: T) => T[]' is not assignable to type 'new <T>(x: T) => string[]'.
!!! error TS2430: Type 'T[]' is not assignable to type 'string[]'.
!!! error TS2430: Type 'T' is not assignable to type 'string'.
a2: new <T>(x: T) => T[]; // error
}
@@ -0,0 +1,142 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(24,11): error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
Types of property 'a' are incompatible.
Type 'new (x: T) => T[]' is not assignable to type 'new <T>(x: T) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(28,11): error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
Types of property 'a2' are incompatible.
Type 'new (x: T) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(32,11): error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
Types of property 'a3' are incompatible.
Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => void'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(36,11): error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
Types of property 'a4' are incompatible.
Type 'new <U>(x: T, y: U) => string' is not assignable to type 'new <T, U>(x: T, y: U) => string'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(40,11): error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
Types of property 'a5' are incompatible.
Type 'new <U>(x: (arg: T) => U) => T' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
Types of parameters 'x' and 'x' are incompatible.
Types of parameters 'arg' and 'arg' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(44,11): error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
Types of property 'a11' are incompatible.
Type 'new <U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
Types of property 'foo' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts(48,11): error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
Types of property 'a16' are incompatible.
Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
Type 'Base' is not assignable to type 'T'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts (7 errors) ====
// checking subtype relations for function types as it relates to contextual signature instantiation
// same as subtypingWithConstructSignatures4 but using class type parameters instead of generic signatures
// all are errors
class Base { foo: string; }
class Derived extends Base { bar: string; }
class Derived2 extends Derived { baz: string; }
class OtherDerived extends Base { bing: string; }
interface A { // T
// M's
a: new <T>(x: T) => T[];
a2: new <T>(x: T) => string[];
a3: new <T>(x: T) => void;
a4: new <T, U>(x: T, y: U) => string;
a5: new <T, U>(x: (arg: T) => U) => T;
a6: new <T extends Base>(x: (arg: T) => Derived) => T;
a11: new <T>(x: { foo: T }, y: { foo: T; bar: T }) => Base;
a15: new <T>(x: { a: T; b: T }) => T[];
a16: new <T extends Base>(x: { a: T; b: T }) => T[];
}
// S's
interface I<T> extends A {
~
!!! error TS2430: Interface 'I<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a' are incompatible.
!!! error TS2430: Type 'new (x: T) => T[]' is not assignable to type 'new <T>(x: T) => T[]'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a: new (x: T) => T[];
}
interface I2<T> extends A {
~~
!!! error TS2430: Interface 'I2<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a2' are incompatible.
!!! error TS2430: Type 'new (x: T) => string[]' is not assignable to type 'new <T>(x: T) => string[]'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a2: new (x: T) => string[];
}
interface I3<T> extends A {
~~
!!! error TS2430: Interface 'I3<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a3' are incompatible.
!!! error TS2430: Type 'new (x: T) => T' is not assignable to type 'new <T>(x: T) => void'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a3: new (x: T) => T;
}
interface I4<T> extends A {
~~
!!! error TS2430: Interface 'I4<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a4' are incompatible.
!!! error TS2430: Type 'new <U>(x: T, y: U) => string' is not assignable to type 'new <T, U>(x: T, y: U) => string'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a4: new <U>(x: T, y: U) => string;
}
interface I5<T> extends A {
~~
!!! error TS2430: Interface 'I5<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a5' are incompatible.
!!! error TS2430: Type 'new <U>(x: (arg: T) => U) => T' is not assignable to type 'new <T, U>(x: (arg: T) => U) => T'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Types of parameters 'arg' and 'arg' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a5: new <U>(x: (arg: T) => U) => T;
}
interface I7<T> extends A {
~~
!!! error TS2430: Interface 'I7<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a11' are incompatible.
!!! error TS2430: Type 'new <U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base' is not assignable to type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type '{ foo: T; }' is not assignable to type '{ foo: T; }'. Two different types with this name exist, but they are unrelated.
!!! error TS2430: Types of property 'foo' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
a11: new <U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
}
interface I9<T> extends A {
~~
!!! error TS2430: Interface 'I9<T>' incorrectly extends interface 'A'.
!!! error TS2430: Types of property 'a16' are incompatible.
!!! error TS2430: Type 'new (x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T extends Base>(x: { a: T; b: T; }) => T[]'.
!!! error TS2430: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2430: Type '{ a: T; b: T; }' is not assignable to type '{ a: T; b: T; }'. Two different types with this name exist, but they are unrelated.
!!! error TS2430: Types of property 'a' are incompatible.
!!! error TS2430: Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.
!!! error TS2430: Type 'Base' is not assignable to type 'T'.
a16: new (x: { a: T; b: T }) => T[];
}
@@ -0,0 +1,48 @@
=== tests/cases/conformance/types/contextualTypes/jsdoc/index.js ===
/** @type {Array<[string, {x?:number, y?:number}]>} */
const arr = [
>arr : Symbol(arr, Decl(index.js, 1, 5))
['a', { x: 1 }],
>x : Symbol(x, Decl(index.js, 2, 11))
['b', { y: 2 }]
>y : Symbol(y, Decl(index.js, 3, 11))
];
/** @return {Array<[string, {x?:number, y?:number}]>} */
function f() {
>f : Symbol(f, Decl(index.js, 4, 2))
return [
['a', { x: 1 }],
>x : Symbol(x, Decl(index.js, 9, 15))
['b', { y: 2 }]
>y : Symbol(y, Decl(index.js, 10, 15))
];
}
class C {
>C : Symbol(C, Decl(index.js, 12, 1))
/** @param {Array<[string, {x?:number, y?:number}]>} value */
set x(value) { }
>x : Symbol(C.x, Decl(index.js, 14, 9), Decl(index.js, 16, 20))
>value : Symbol(value, Decl(index.js, 16, 10))
get x() {
>x : Symbol(C.x, Decl(index.js, 14, 9), Decl(index.js, 16, 20))
return [
['a', { x: 1 }],
>x : Symbol(x, Decl(index.js, 19, 19))
['b', { y: 2 }]
>y : Symbol(y, Decl(index.js, 20, 19))
];
}
}
@@ -0,0 +1,77 @@
=== tests/cases/conformance/types/contextualTypes/jsdoc/index.js ===
/** @type {Array<[string, {x?:number, y?:number}]>} */
const arr = [
>arr : [string, { x?: number; y?: number; }][]
>[ ['a', { x: 1 }], ['b', { y: 2 }]] : ([string, { x: number; }] | [string, { y: number; }])[]
['a', { x: 1 }],
>['a', { x: 1 }] : [string, { x: number; }]
>'a' : "a"
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
['b', { y: 2 }]
>['b', { y: 2 }] : [string, { y: number; }]
>'b' : "b"
>{ y: 2 } : { y: number; }
>y : number
>2 : 2
];
/** @return {Array<[string, {x?:number, y?:number}]>} */
function f() {
>f : () => [string, { x?: number; y?: number; }][]
return [
>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ([string, { x: number; }] | [string, { y: number; }])[]
['a', { x: 1 }],
>['a', { x: 1 }] : [string, { x: number; }]
>'a' : "a"
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
['b', { y: 2 }]
>['b', { y: 2 }] : [string, { y: number; }]
>'b' : "b"
>{ y: 2 } : { y: number; }
>y : number
>2 : 2
];
}
class C {
>C : C
/** @param {Array<[string, {x?:number, y?:number}]>} value */
set x(value) { }
>x : [string, { x?: number; y?: number; }][]
>value : [string, { x?: number; y?: number; }][]
get x() {
>x : [string, { x?: number; y?: number; }][]
return [
>[ ['a', { x: 1 }], ['b', { y: 2 }] ] : ([string, { x: number; }] | [string, { y: number; }])[]
['a', { x: 1 }],
>['a', { x: 1 }] : [string, { x: number; }]
>'a' : "a"
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
['b', { y: 2 }]
>['b', { y: 2 }] : [string, { y: number; }]
>'b' : "b"
>{ y: 2 } : { y: number; }
>y : number
>2 : 2
];
}
}
@@ -16,9 +16,9 @@ var f2: {
};
f2 = (x, y) => { return x }
>f2 = (x, y) => { return x } : (x: T, y: U) => T
>f2 = (x, y) => { return x } : <T, U>(x: T, y: U) => T
>f2 : <T, U>(x: T, y: U) => T
>(x, y) => { return x } : (x: T, y: U) => T
>(x, y) => { return x } : <T, U>(x: T, y: U) => T
>x : T
>y : U
>x : T
@@ -0,0 +1,30 @@
tests/cases/compiler/excessPropertyCheckWithSpread.ts(6,3): error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'.
tests/cases/compiler/excessPropertyCheckWithSpread.ts(16,3): error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'.
==== tests/cases/compiler/excessPropertyCheckWithSpread.ts (2 errors) ====
declare function f({ a: number }): void
interface I {
readonly n: number;
}
declare let i: I;
f({ a: 1, ...i });
~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ n: number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
!!! error TS2345: Object literal may only specify known properties, and 'n' does not exist in type '{ a: any; }'.
interface R {
opt?: number
}
interface L {
opt: string
}
declare let l: L;
declare let r: R;
f({ a: 1, ...l, ...r });
~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ opt: string | number; a: number; }' is not assignable to parameter of type '{ a: any; }'.
!!! error TS2345: Object literal may only specify known properties, and 'opt' does not exist in type '{ a: any; }'.
@@ -0,0 +1,30 @@
//// [excessPropertyCheckWithSpread.ts]
declare function f({ a: number }): void
interface I {
readonly n: number;
}
declare let i: I;
f({ a: 1, ...i });
interface R {
opt?: number
}
interface L {
opt: string
}
declare let l: L;
declare let r: R;
f({ a: 1, ...l, ...r });
//// [excessPropertyCheckWithSpread.js]
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
f(__assign({ a: 1 }, i));
f(__assign({ a: 1 }, l, r));
@@ -45,7 +45,5 @@ g("", x => null, x => x.toLowerCase());
>g : Symbol(g, Decl(fixingTypeParametersRepeatedly1.ts, 1, 39), Decl(fixingTypeParametersRepeatedly1.ts, 4, 63))
>x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 5))
>x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 16))
>x.toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
>x : Symbol(x, Decl(fixingTypeParametersRepeatedly1.ts, 6, 16))
>toLowerCase : Symbol(String.toLowerCase, Decl(lib.d.ts, --, --))
@@ -48,16 +48,16 @@ declare function g();
>g : { <T>(x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; }
g("", x => null, x => x.toLowerCase());
>g("", x => null, x => x.toLowerCase()) : string
>g("", x => null, x => x.toLowerCase()) : any
>g : { <T>(x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; }
>"" : ""
>x => null : (x: string) => any
>x : string
>null : null
>x => x.toLowerCase() : (x: string) => string
>x : string
>x.toLowerCase() : string
>x.toLowerCase : () => string
>x : string
>toLowerCase : () => string
>x => x.toLowerCase() : (x: any) => any
>x : any
>x.toLowerCase() : any
>x.toLowerCase : any
>x : any
>toLowerCase : any
@@ -1,11 +1,9 @@
tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(11,27): error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'.
Type 'Base' is not assignable to type 'Derived'.
Property 'toBase' is missing in type 'Base'.
tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(17,27): error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'.
Type 'Base' is not assignable to type 'Derived'.
==== tests/cases/compiler/fixingTypeParametersRepeatedly2.ts (2 errors) ====
==== tests/cases/compiler/fixingTypeParametersRepeatedly2.ts (1 errors) ====
interface Base {
baseProp;
}
@@ -26,7 +24,4 @@ tests/cases/compiler/fixingTypeParametersRepeatedly2.ts(17,27): error TS2345: Ar
// The same error should be observed in both cases.
declare function bar<T>(x: T, func: (p: T) => T): T;
declare function bar<T>(x: T, func: (p: T) => T): T;
var result = bar(derived, d => d.toBase());
~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '(d: Derived) => Base' is not assignable to parameter of type '(p: Derived) => Derived'.
!!! error TS2345: Type 'Base' is not assignable to type 'Derived'.
var result = bar(derived, d => d.toBase());
@@ -66,8 +66,8 @@ declare function bar<T>(x: T, func: (p: T) => T): T;
>T : T
var result2 = bar(derived, d => d.toBase());
>result2 : Derived
>bar(derived, d => d.toBase()) : Derived
>result2 : Base
>bar(derived, d => d.toBase()) : Base
>bar : { <T>(x: T, func: (p: T) => T): T; <T>(x: T, func: (p: T) => T): T; }
>derived : Derived
>d => d.toBase() : (d: Derived) => Base
@@ -1,7 +1,9 @@
tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(9,1): error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
Type '{}[]' is not assignable to type 'T'.
tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(12,1): error TS2304: Cannot find name 'console'.
==== tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts (1 errors) ====
==== tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts (2 errors) ====
var f : {
<T>(x:T): T;
}
@@ -11,6 +13,9 @@ tests/cases/compiler/functionTypeArgumentAssignmentCompat.ts(12,1): error TS2304
} = () => [];
f = g;
~
!!! error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Type '{}[]' is not assignable to type 'T'.
var s = f("str").toUpperCase();
console.log(s);
@@ -1,11 +1,12 @@
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,14): error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<State>'.
Type 'State | 1' is not assignable to type 'State'.
Type '1' is not assignable to type 'State'.
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(24,61): error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
Type 'State | 1' is not assignable to type 'StrategicState'.
Type '1' has no properties in common with type 'StrategicState'.
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(29,70): error TS7025: Generator implicitly has type 'IterableIterator<any>' because it does not yield any values. Consider supplying a return type.
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(32,42): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
Type argument candidate 'State' is not a valid type argument because it is not a supertype of candidate '1'.
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,62): error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
==== tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts (4 errors) ====
@@ -33,11 +34,11 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): err
}
export const Nothing: Strategy<State> = strategy("Nothing", function* (state: State) {
~~~~~~~
!!! error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
!!! error TS2322: Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<State>'.
!!! error TS2322: Type 'State | 1' is not assignable to type 'State'.
!!! error TS2322: Type '1' is not assignable to type 'State'.
~~~~~~~~
!!! error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
!!! error TS2345: Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
!!! error TS2345: Type 'State | 1' is not assignable to type 'StrategicState'.
!!! error TS2345: Type '1' has no properties in common with type 'StrategicState'.
yield 1;
return state;
});
@@ -55,8 +56,9 @@ tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck63.ts(36,14): err
});
export const Nothing3: Strategy<State> = strategy("Nothing", function* (state: State) {
~~~~~~~~
!!! error TS2322: Type '(a: State | 1) => IterableIterator<State | 1>' is not assignable to type 'Strategy<State>'.
~~~~~~~~
!!! error TS2345: Argument of type '(state: State) => IterableIterator<State | 1>' is not assignable to parameter of type '(a: StrategicState) => IterableIterator<StrategicState>'.
!!! error TS2345: Type 'IterableIterator<State | 1>' is not assignable to type 'IterableIterator<StrategicState>'.
yield state;
return 1;
});
@@ -0,0 +1,30 @@
tests/cases/compiler/genericArgumentCallSigAssignmentCompat.ts(16,31): error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
Type 'string | number | boolean' is not assignable to type 'boolean'.
Type 'string' is not assignable to type 'boolean'.
==== tests/cases/compiler/genericArgumentCallSigAssignmentCompat.ts (1 errors) ====
module Underscore {
export interface Iterator<T, U> {
(value: T, index: any, list: any): U;
}
export interface Static {
all<T>(list: T[], iterator?: Iterator<T, boolean>, context?: any): boolean;
identity<T>(value: T): T;
}
}
declare var _: Underscore.Static;
// No error, Call signatures of types '<T>(value: T) => T' and 'Underscore.Iterator<{}, boolean>' are compatible when instantiated with any.
// Ideally, we would not have a generic signature here, because it should be instantiated with {} during inferential typing
_.all([true, 1, null, 'yes'], _.identity);
~~~~~~~~~~
!!! error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
!!! error TS2345: Type 'string | number | boolean' is not assignable to type 'boolean'.
!!! error TS2345: Type 'string' is not assignable to type 'boolean'.
// Ok, because fixing makes us infer boolean for T
_.all([true], _.identity);
@@ -0,0 +1,34 @@
tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts(4,1): error TS2322: Type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void'.
Types of parameters 'z' and 'z' are incompatible.
Type 'U' is not assignable to type '{ a: T; b: number; }'.
Type '{ a: T; b: string; }' is not assignable to type '{ a: T; b: number; }'.
Types of property 'b' are incompatible.
Type 'string' is not assignable to type 'number'.
tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts(5,1): error TS2322: Type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void'.
Types of parameters 'z' and 'z' are incompatible.
Type 'U' is not assignable to type '{ a: T; b: string; }'.
Type '{ a: T; b: number; }' is not assignable to type '{ a: T; b: string; }'.
Types of property 'b' are incompatible.
Type 'number' is not assignable to type 'string'.
==== tests/cases/compiler/genericAssignmentCompatOfFunctionSignatures1.ts (2 errors) ====
var x1 = function foo3<T, U extends { a: T; b: string }>(x: T, z: U) { }
var x2 = function foo3<T, U extends { a: T; b: number }>(x: T, z: U) { }
x1 = x2;
~~
!!! error TS2322: Type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void'.
!!! error TS2322: Types of parameters 'z' and 'z' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type '{ a: T; b: number; }'.
!!! error TS2322: Type '{ a: T; b: string; }' is not assignable to type '{ a: T; b: number; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
x2 = x1;
~~
!!! error TS2322: Type '<T, U extends { a: T; b: string; }>(x: T, z: U) => void' is not assignable to type '<T, U extends { a: T; b: number; }>(x: T, z: U) => void'.
!!! error TS2322: Types of parameters 'z' and 'z' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type '{ a: T; b: string; }'.
!!! error TS2322: Type '{ a: T; b: number; }' is not assignable to type '{ a: T; b: string; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
@@ -125,7 +125,7 @@ const f01: <A>(x: A) => A[] = x => [x];
>x : A
>A : A
>A : A
>x => [x] : (x: A) => A[]
>x => [x] : <A>(x: A) => A[]
>x : A
>[x] : A[]
>x : A
@@ -356,7 +356,7 @@ type fn = <A>(a: A) => A;
const fn: fn = a => a;
>fn : fn
>fn : fn
>a => a : (a: A) => A
>a => a : <A>(a: A) => A
>a : A
>a : A
@@ -1,13 +1,18 @@
tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts(6,1): error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
Type '{}[]' is not assignable to type 'T'.
tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts(10,1): error TS2304: Cannot find name 'console'.
==== tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts (1 errors) ====
==== tests/cases/compiler/genericFunctionCallSignatureReturnTypeMismatch.ts (2 errors) ====
interface Array<T> {}
var f : { <T>(x:T): T; }
var g : { <S>() : S[]; };
f = g;
~
!!! error TS2322: Type '<S>() => S[]' is not assignable to type '<T>(x: T) => T'.
!!! error TS2322: Type '{}[]' is not assignable to type 'T'.
var s = f("str").toUpperCase();
@@ -9,11 +9,11 @@ function f(p: <T>(x: T) => void) { };
f(x => f(y => x = y));
>f(x => f(y => x = y)) : void
>f : (p: <T>(x: T) => void) => void
>x => f(y => x = y) : (x: T) => void
>x => f(y => x = y) : <T>(x: T) => void
>x : T
>f(y => x = y) : void
>f : (p: <T>(x: T) => void) => void
>y => x = y : (y: T) => T
>y => x = y : <T>(y: T) => T
>y : T
>x = y : T
>x : T
@@ -0,0 +1,32 @@
tests/cases/compiler/genericImplements.ts(8,7): error TS2420: Class 'X' incorrectly implements interface 'I'.
Types of property 'f' are incompatible.
Type '<T extends B>() => T' is not assignable to type '<T extends A>() => T'.
Type 'B' is not assignable to type 'T'.
==== tests/cases/compiler/genericImplements.ts (1 errors) ====
class A { a; };
class B { b; };
interface I {
f<T extends A>(): T;
} // { f: () => { a; } }
// OK
class X implements I {
~
!!! error TS2420: Class 'X' incorrectly implements interface 'I'.
!!! error TS2420: Types of property 'f' are incompatible.
!!! error TS2420: Type '<T extends B>() => T' is not assignable to type '<T extends A>() => T'.
!!! error TS2420: Type 'B' is not assignable to type 'T'.
f<T extends B>(): T { return undefined; }
} // { f: () => { b; } }
// OK
class Y implements I {
f<T extends A>(): T { return undefined; }
} // { f: () => { a; } }
// OK
class Z implements I {
f<T>(): T { return undefined; }
} // { f: <T>() => T }
@@ -0,0 +1,40 @@
tests/cases/compiler/genericSpecializations1.ts(5,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
Types of property 'foo' are incompatible.
Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'string'.
tests/cases/compiler/genericSpecializations1.ts(9,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
Types of property 'foo' are incompatible.
Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'string'.
==== tests/cases/compiler/genericSpecializations1.ts (2 errors) ====
interface IFoo<T> {
foo<T>(x: T): T; // no error on implementors because IFoo's T is different from foo's T
}
class IntFooBad implements IFoo<number> {
~~~~~~~~~
!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
!!! error TS2420: Types of property 'foo' are incompatible.
!!! error TS2420: Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
!!! error TS2420: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2420: Type 'T' is not assignable to type 'string'.
foo(x: string): string { return null; }
}
class StringFoo2 implements IFoo<string> {
~~~~~~~~~~
!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
!!! error TS2420: Types of property 'foo' are incompatible.
!!! error TS2420: Type '(x: string) => string' is not assignable to type '<T>(x: T) => T'.
!!! error TS2420: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2420: Type 'T' is not assignable to type 'string'.
foo(x: string): string { return null; }
}
class StringFoo3 implements IFoo<string> {
foo<T>(x: T): T { return null; }
}
@@ -1,8 +1,18 @@
tests/cases/compiler/genericSpecializations2.ts(7,7): error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
Types of property 'foo' are incompatible.
Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'string'.
tests/cases/compiler/genericSpecializations2.ts(8,9): error TS2368: Type parameter name cannot be 'string'.
tests/cases/compiler/genericSpecializations2.ts(11,7): error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
Types of property 'foo' are incompatible.
Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type 'T' is not assignable to type 'string'.
tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parameter name cannot be 'string'.
==== tests/cases/compiler/genericSpecializations2.ts (2 errors) ====
==== tests/cases/compiler/genericSpecializations2.ts (4 errors) ====
class IFoo<T> {
foo<T>(x: T): T { // no error on implementors because IFoo's T is different from foo's T
return null;
@@ -10,12 +20,24 @@ tests/cases/compiler/genericSpecializations2.ts(12,9): error TS2368: Type parame
}
class IntFooBad implements IFoo<number> {
~~~~~~~~~
!!! error TS2420: Class 'IntFooBad' incorrectly implements interface 'IFoo<number>'.
!!! error TS2420: Types of property 'foo' are incompatible.
!!! error TS2420: Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
!!! error TS2420: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2420: Type 'T' is not assignable to type 'string'.
foo<string>(x: string): string { return null; }
~~~~~~
!!! error TS2368: Type parameter name cannot be 'string'.
}
class StringFoo2 implements IFoo<string> {
~~~~~~~~~~
!!! error TS2420: Class 'StringFoo2' incorrectly implements interface 'IFoo<string>'.
!!! error TS2420: Types of property 'foo' are incompatible.
!!! error TS2420: Type '<string>(x: string) => string' is not assignable to type '<T>(x: T) => T'.
!!! error TS2420: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2420: Type 'T' is not assignable to type 'string'.
foo<string>(x: string): string { return null; }
~~~~~~
!!! error TS2368: Type parameter name cannot be 'string'.
@@ -0,0 +1,26 @@
tests/cases/compiler/genericTypeArgumentInference1.ts(12,39): error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
Type 'string | number | boolean' is not assignable to type 'boolean'.
Type 'string' is not assignable to type 'boolean'.
==== tests/cases/compiler/genericTypeArgumentInference1.ts (1 errors) ====
module Underscore {
export interface Iterator<T, U> {
(value: T, index: any, list: any): U;
}
export interface Static {
all<T>(list: T[], iterator?: Iterator<T, boolean>, context?: any): T;
identity<T>(value: T): T;
}
}
declare var _: Underscore.Static;
var r = _.all([true, 1, null, 'yes'], _.identity);
~~~~~~~~~~
!!! error TS2345: Argument of type '<T>(value: T) => T' is not assignable to parameter of type 'Iterator<string | number | boolean, boolean>'.
!!! error TS2345: Type 'string | number | boolean' is not assignable to type 'boolean'.
!!! error TS2345: Type 'string' is not assignable to type 'boolean'.
var r2 = _.all([true], _.identity);
var r3 = _.all([], _.identity);
var r4 = _.all([<any>true], _.identity);
@@ -6,8 +6,8 @@ var r = < <T>(x: T) => T > ((x) => { return null; }); // bug was 'could not find
>x : T
>T : T
>T : T
>((x) => { return null; }) : (x: T) => any
>(x) => { return null; } : (x: T) => any
>((x) => { return null; }) : <T>(x: T) => any
>(x) => { return null; } : <T>(x: T) => any
>x : T
>null : null
@@ -18,11 +18,11 @@ var c: Comparer<any>;
>Comparer : Comparer<T>
c = { compareTo: (x, y) => { return y; } };
>c = { compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; }
>c = { compareTo: (x, y) => { return y; } } : { compareTo: <U>(x: any, y: U) => U; }
>c : Comparer<any>
>{ compareTo: (x, y) => { return y; } } : { compareTo: (x: any, y: U) => U; }
>compareTo : (x: any, y: U) => U
>(x, y) => { return y; } : (x: any, y: U) => U
>{ compareTo: (x, y) => { return y; } } : { compareTo: <U>(x: any, y: U) => U; }
>compareTo : <U>(x: any, y: U) => U
>(x, y) => { return y; } : <U>(x: any, y: U) => U
>x : any
>y : U
>y : U
@@ -0,0 +1,28 @@
//// [incrementOnNullAssertion.ts]
interface Dictionary<T> {
[myFavouriteType: string]: T | undefined
}
const x = 'bar'
let foo: Dictionary<number> = {}
if (foo[x] === undefined) {
foo[x] = 1
}
else {
let nu = foo[x]
let n = foo[x]
foo[x]!++
}
//// [incrementOnNullAssertion.js]
"use strict";
var x = 'bar';
var foo = {};
if (foo[x] === undefined) {
foo[x] = 1;
}
else {
var nu = foo[x];
var n = foo[x];
foo[x]++;
}
@@ -0,0 +1,41 @@
=== tests/cases/compiler/incrementOnNullAssertion.ts ===
interface Dictionary<T> {
>Dictionary : Symbol(Dictionary, Decl(incrementOnNullAssertion.ts, 0, 0))
>T : Symbol(T, Decl(incrementOnNullAssertion.ts, 0, 21))
[myFavouriteType: string]: T | undefined
>myFavouriteType : Symbol(myFavouriteType, Decl(incrementOnNullAssertion.ts, 1, 5))
>T : Symbol(T, Decl(incrementOnNullAssertion.ts, 0, 21))
}
const x = 'bar'
>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5))
let foo: Dictionary<number> = {}
>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3))
>Dictionary : Symbol(Dictionary, Decl(incrementOnNullAssertion.ts, 0, 0))
if (foo[x] === undefined) {
>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3))
>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5))
>undefined : Symbol(undefined)
foo[x] = 1
>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3))
>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5))
}
else {
let nu = foo[x]
>nu : Symbol(nu, Decl(incrementOnNullAssertion.ts, 9, 7))
>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3))
>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5))
let n = foo[x]
>n : Symbol(n, Decl(incrementOnNullAssertion.ts, 10, 7))
>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3))
>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5))
foo[x]!++
>foo : Symbol(foo, Decl(incrementOnNullAssertion.ts, 4, 3))
>x : Symbol(x, Decl(incrementOnNullAssertion.ts, 3, 5))
}
@@ -0,0 +1,53 @@
=== tests/cases/compiler/incrementOnNullAssertion.ts ===
interface Dictionary<T> {
>Dictionary : Dictionary<T>
>T : T
[myFavouriteType: string]: T | undefined
>myFavouriteType : string
>T : T
}
const x = 'bar'
>x : "bar"
>'bar' : "bar"
let foo: Dictionary<number> = {}
>foo : Dictionary<number>
>Dictionary : Dictionary<T>
>{} : {}
if (foo[x] === undefined) {
>foo[x] === undefined : boolean
>foo[x] : number | undefined
>foo : Dictionary<number>
>x : "bar"
>undefined : undefined
foo[x] = 1
>foo[x] = 1 : 1
>foo[x] : number | undefined
>foo : Dictionary<number>
>x : "bar"
>1 : 1
}
else {
let nu = foo[x]
>nu : number | undefined
>foo[x] : number | undefined
>foo : Dictionary<number>
>x : "bar"
let n = foo[x]
>n : number | undefined
>foo[x] : number | undefined
>foo : Dictionary<number>
>x : "bar"
foo[x]!++
>foo[x]!++ : number
>foo[x]! : number
>foo[x] : number | undefined
>foo : Dictionary<number>
>x : "bar"
}
@@ -35,4 +35,14 @@
declare type T = number;
export = T;
==== /node_modules/foo/bar.d.ts (0 errors) ====
export type T = number;
==== /node_modules/foo/index.d.ts (0 errors) ====
export { T } from "./bar"; // In a declaration file, so not an error.
==== /node_modules/baz/index.d.ts (0 errors) ====
declare module "baz" {
export { T } from "foo"; // Also allowed.
}
@@ -9,7 +9,17 @@ export class C {}
//// [exportEqualsT.ts]
declare type T = number;
export = T;
//// [bar.d.ts]
export type T = number;
//// [index.d.ts]
export { T } from "./bar"; // In a declaration file, so not an error.
//// [index.d.ts]
declare module "baz" {
export { T } from "foo"; // Also allowed.
}
//// [user.ts]
// Error, can't re-export something that's only a type.
@@ -3,9 +3,10 @@ tests/cases/compiler/jsdocInTypeScript.ts(23,33): error TS2362: The left-hand si
tests/cases/compiler/jsdocInTypeScript.ts(25,3): error TS2345: Argument of type '1' is not assignable to parameter of type 'boolean'.
tests/cases/compiler/jsdocInTypeScript.ts(25,15): error TS2339: Property 'length' does not exist on type 'number'.
tests/cases/compiler/jsdocInTypeScript.ts(30,3): error TS2339: Property 'x' does not exist on type '{}'.
tests/cases/compiler/jsdocInTypeScript.ts(42,12): error TS2503: Cannot find namespace 'N'.
==== tests/cases/compiler/jsdocInTypeScript.ts (5 errors) ====
==== tests/cases/compiler/jsdocInTypeScript.ts (6 errors) ====
// JSDoc typedef tags are not bound TypeScript files.
/** @typedef {function} T */
declare const x: T;
@@ -43,7 +44,21 @@ tests/cases/compiler/jsdocInTypeScript.ts(30,3): error TS2339: Property 'x' does
// @type has no effect either.
/** @type {{ x?: number }} */
const z = {};
z.x = 1;
z.x = 1; // Error
~
!!! error TS2339: Property 'x' does not exist on type '{}'.
// @template tag should not interfere with constraint or default.
/** @template T */
interface I<T extends number = 0> {}
/** @template T */
function tem<T extends number>(t: T): I<T> { return {}; }
let i: I; // Should succeed thanks to type parameter default
/** @typedef {string} N.Str */
import M = N; // Error: @typedef does not create namespaces in TypeScript code.
~
!!! error TS2503: Cannot find namespace 'N'.
+19 -2
View File
@@ -28,7 +28,19 @@ f(1); f(true).length;
// @type has no effect either.
/** @type {{ x?: number }} */
const z = {};
z.x = 1;
z.x = 1; // Error
// @template tag should not interfere with constraint or default.
/** @template T */
interface I<T extends number = 0> {}
/** @template T */
function tem<T extends number>(t: T): I<T> { return {}; }
let i: I; // Should succeed thanks to type parameter default
/** @typedef {string} N.Str */
import M = N; // Error: @typedef does not create namespaces in TypeScript code.
//// [jsdocInTypeScript.js]
@@ -50,4 +62,9 @@ f(true).length;
// @type has no effect either.
/** @type {{ x?: number }} */
var z = {};
z.x = 1;
z.x = 1; // Error
/** @template T */
function tem(t) { return {}; }
var i; // Should succeed thanks to type parameter default
/** @typedef {string} N.Str */
var M = N; // Error: @typedef does not create namespaces in TypeScript code.
@@ -0,0 +1,36 @@
=== tests/cases/conformance/jsdoc/jsdocTemplateTag.ts ===
/**
* @param {T} a
* @template T
*/
function f<T>(a: T) {
>f : Symbol(f, Decl(jsdocTemplateTag.ts, 0, 0))
>T : Symbol(T, Decl(jsdocTemplateTag.ts, 4, 11))
>a : Symbol(a, Decl(jsdocTemplateTag.ts, 4, 14))
>T : Symbol(T, Decl(jsdocTemplateTag.ts, 4, 11))
return () => a
>a : Symbol(a, Decl(jsdocTemplateTag.ts, 4, 14))
}
let n = f(1)()
>n : Symbol(n, Decl(jsdocTemplateTag.ts, 7, 3))
>f : Symbol(f, Decl(jsdocTemplateTag.ts, 0, 0))
/**
* @param {T} a
* @template T
* @returns {function(): T}
*/
function g<T>(a: T) {
>g : Symbol(g, Decl(jsdocTemplateTag.ts, 7, 14))
>T : Symbol(T, Decl(jsdocTemplateTag.ts, 14, 11))
>a : Symbol(a, Decl(jsdocTemplateTag.ts, 14, 14))
>T : Symbol(T, Decl(jsdocTemplateTag.ts, 14, 11))
return () => a
>a : Symbol(a, Decl(jsdocTemplateTag.ts, 14, 14))
}
let s = g('hi')()
>s : Symbol(s, Decl(jsdocTemplateTag.ts, 17, 3))
>g : Symbol(g, Decl(jsdocTemplateTag.ts, 7, 14))
@@ -0,0 +1,44 @@
=== tests/cases/conformance/jsdoc/jsdocTemplateTag.ts ===
/**
* @param {T} a
* @template T
*/
function f<T>(a: T) {
>f : <T>(a: T) => () => T
>T : T
>a : T
>T : T
return () => a
>() => a : () => T
>a : T
}
let n = f(1)()
>n : number
>f(1)() : number
>f(1) : () => number
>f : <T>(a: T) => () => T
>1 : 1
/**
* @param {T} a
* @template T
* @returns {function(): T}
*/
function g<T>(a: T) {
>g : <T>(a: T) => () => T
>T : T
>a : T
>T : T
return () => a
>() => a : () => T
>a : T
}
let s = g('hi')()
>s : string
>g('hi')() : string
>g('hi') : () => string
>g : <T>(a: T) => () => T
>'hi' : "hi"

Some files were not shown because too many files have changed in this diff Show More