Skip to content

Unnecessary elaboration about not being assignable to type parameters #42952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17154,6 +17154,7 @@ namespace ts {
);
}
else {
errorInfo = undefined;
reportError(
Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1,
targetType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
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.
'T' could be instantiated with an arbitrary type which could be unrelated to 'T'.
Type 'Base' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'.
Comment on lines 46 to -49
Copy link
Contributor Author

@jonhue jonhue Feb 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing which I'm not 100% certain about based on the original issue, is whether we want to continue elaborating if the target and source type are the same. Like in this case where both are T. What do you think?

Theoretically, we could also be even more conservative by only stopping elaboration when the target is some type parameter (e.g. T) and the source is a union of that type parameter and something else (e.g. T | SomeOtherType).



==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSignatureAssignabilityInInheritance6.ts (7 errors) ====
Expand Down Expand Up @@ -152,7 +150,5 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/callSign
!!! 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: 'T' could be instantiated with an arbitrary type which could be unrelated to 'T'.
!!! error TS2430: Type 'Base' is not assignable to type 'T'.
!!! error TS2430: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'.
a16: (x: { a: T; b: T }) => T[];
}
12 changes: 0 additions & 12 deletions tests/baselines/reference/conditionalTypes1.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(159,5): error TS2
'ZeroOf<T>' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
Type '0 | (T extends string ? "" : false)' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to '0 | (T extends string ? "" : false)'.
Type 'number' is not assignable to type 'T'.
'number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
Type 'string | number' is not assignable to type 'T'.
'string | number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
Type 'string' is not assignable to type 'T'.
'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
tests/cases/conformance/types/conditional/conditionalTypes1.ts(160,5): error TS2322: Type 'T' is not assignable to type 'ZeroOf<T>'.
Type 'string | number' is not assignable to type 'ZeroOf<T>'.
Type 'string' is not assignable to type 'ZeroOf<T>'.
Expand Down Expand Up @@ -303,12 +297,6 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
!!! error TS2322: 'ZeroOf<T>' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
!!! error TS2322: Type '0 | (T extends string ? "" : false)' is not assignable to type 'T'.
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to '0 | (T extends string ? "" : false)'.
!!! error TS2322: Type 'number' is not assignable to type 'T'.
!!! error TS2322: 'number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'T'.
!!! error TS2322: 'string | number' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
!!! error TS2322: Type 'string' is not assignable to type 'T'.
!!! error TS2322: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string | number'.
y = x; // Error
~
!!! error TS2322: Type 'T' is not assignable to type 'ZeroOf<T>'.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
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.
'T' could be instantiated with an arbitrary type which could be unrelated to 'T'.
Type 'Base' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'.


==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/constructSignatureAssignabilityInInheritance6.ts (7 errors) ====
Expand Down Expand Up @@ -152,7 +150,5 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/construc
!!! 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: 'T' could be instantiated with an arbitrary type which could be unrelated to 'T'.
!!! error TS2430: Type 'Base' is not assignable to type 'T'.
!!! error TS2430: 'T' could be instantiated with an arbitrary type which could be unrelated to 'Base'.
a16: new (x: { a: T; b: T }) => T[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts(3,3): error TS2322: Type 'T | Yadda' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'T | Yadda'.


==== tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts (1 errors) ====
async function foo<T>(x: T): Promise<T> {
let yaddable = await getXOrYadda(x);
return yaddable;
~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'T | Yadda' is not assignable to type 'T'.
!!! error TS2322: 'T' could be instantiated with an arbitrary type which could be unrelated to 'T | Yadda'.
}

interface Yadda {
stuff: string,
things: string,
}

declare function getXOrYadda<T>(x: T): T | Yadda;

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//// [doNotElaborateAssignabilityToTypeParameters.ts]
async function foo<T>(x: T): Promise<T> {
let yaddable = await getXOrYadda(x);
return yaddable;
}

interface Yadda {
stuff: string,
things: string,
}

declare function getXOrYadda<T>(x: T): T | Yadda;


//// [doNotElaborateAssignabilityToTypeParameters.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
function foo(x) {
return __awaiter(this, void 0, void 0, function () {
var yaddable;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getXOrYadda(x)];
case 1:
yaddable = _a.sent();
return [2 /*return*/, yaddable];
}
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
=== tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts ===
async function foo<T>(x: T): Promise<T> {
>foo : Symbol(foo, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 0, 0))
>T : Symbol(T, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 0, 19))
>x : Symbol(x, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 0, 22))
>T : Symbol(T, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 0, 19))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>T : Symbol(T, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 0, 19))

let yaddable = await getXOrYadda(x);
>yaddable : Symbol(yaddable, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 1, 5))
>getXOrYadda : Symbol(getXOrYadda, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 8, 1))
>x : Symbol(x, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 0, 22))

return yaddable;
>yaddable : Symbol(yaddable, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 1, 5))
}

interface Yadda {
>Yadda : Symbol(Yadda, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 3, 1))

stuff: string,
>stuff : Symbol(Yadda.stuff, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 5, 17))

things: string,
>things : Symbol(Yadda.things, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 6, 16))
}

declare function getXOrYadda<T>(x: T): T | Yadda;
>getXOrYadda : Symbol(getXOrYadda, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 8, 1))
>T : Symbol(T, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 10, 29))
>x : Symbol(x, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 10, 32))
>T : Symbol(T, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 10, 29))
>T : Symbol(T, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 10, 29))
>Yadda : Symbol(Yadda, Decl(doNotElaborateAssignabilityToTypeParameters.ts, 3, 1))

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
=== tests/cases/compiler/doNotElaborateAssignabilityToTypeParameters.ts ===
async function foo<T>(x: T): Promise<T> {
>foo : <T>(x: T) => Promise<T>
>x : T

let yaddable = await getXOrYadda(x);
>yaddable : T | Yadda
>await getXOrYadda(x) : T | Yadda
>getXOrYadda(x) : T | Yadda
>getXOrYadda : <T>(x: T) => T | Yadda
>x : T

return yaddable;
>yaddable : T | Yadda
}

interface Yadda {
stuff: string,
>stuff : string

things: string,
>things : string
}

declare function getXOrYadda<T>(x: T): T | Yadda;
>getXOrYadda : <T>(x: T) => T | Yadda
>x : T

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/genericC
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/genericCallWithObjectTypeArgsAndInitializers.ts(8,56): error TS2322: Type 'U' is not assignable to type 'V'.
'V' could be instantiated with an arbitrary type which could be unrelated to 'U'.
Type 'T' is not assignable to type 'V'.
'V' could be instantiated with an arbitrary type which could be unrelated to 'T'.


==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/genericCallWithObjectTypeArgsAndInitializers.ts (3 errors) ====
Expand All @@ -26,6 +24,4 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/genericC
~~~~~~~~
!!! error TS2322: Type 'U' is not assignable to type 'V'.
!!! error TS2322: 'V' could be instantiated with an arbitrary type which could be unrelated to 'U'.
!!! error TS2322: Type 'T' is not assignable to type 'V'.
!!! error TS2322: 'V' could be instantiated with an arbitrary type which could be unrelated to 'T'.
function foo7<T, U extends T, V extends U>(x: V, y: U = x) { } // should be ok
18 changes: 0 additions & 18 deletions tests/baselines/reference/mappedTypeRelationships.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2
Type 'T[string]' is not assignable to type 'U[keyof T]'.
Type 'T' is not assignable to type 'U'.
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
Type 'T' is not assignable to type 'U'.
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'.
Type 'undefined' is not assignable to type 'T[K]'.
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'.
Expand All @@ -32,12 +29,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2
Type 'T[string]' is not assignable to type 'U[K]'.
Type 'T' is not assignable to type 'U'.
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
Type 'T[keyof T]' is not assignable to type 'U[K]'.
Type 'T' is not assignable to type 'U'.
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
Type 'T[K]' is not assignable to type 'U[K]'.
Type 'T' is not assignable to type 'U'.
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly<T>' only permits reading.
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly<T>' only permits reading.
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
Expand Down Expand Up @@ -162,9 +153,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
}

function f13<T, U extends T, K extends keyof T>(x: T, y: Partial<U>, k: K) {
Expand All @@ -181,12 +169,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[K]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
!!! error TS2322: Type 'T' is not assignable to type 'U'.
!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
}

function f20<T>(x: T, y: Readonly<T>, k: keyof T) {
Expand Down
Loading