Skip to content

Commit

Permalink
[release-4.5] Exclude identity relation from mapped type relation che…
Browse files Browse the repository at this point in the history
…ck (#46635)

* Exclude identity relation from mapped type relation check

* Add regression test

Co-authored-by: Anders Hejlsberg <andersh@microsoft.com>
  • Loading branch information
DanielRosenwasser and ahejlsberg committed Nov 5, 2021
1 parent df53f4d commit b8ee330
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Expand Up @@ -19047,7 +19047,7 @@ namespace ts {
originalErrorInfo = undefined;
}
}
else if (isGenericMappedType(target)) {
else if (isGenericMappedType(target) && relation !== identityRelation) {
// Check if source type `S` is related to target type `{ [P in Q]: T }` or `{ [P in Q as R]: T}`.
const keysRemapped = !!target.declaration.nameType;
const templateType = getTemplateTypeFromMappedType(target);
Expand Down
22 changes: 22 additions & 0 deletions tests/baselines/reference/noExcessiveStackDepthError.errors.txt
@@ -0,0 +1,22 @@
tests/cases/compiler/noExcessiveStackDepthError.ts(13,9): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'FindConditions<any>', but here has type 'FindConditions<Entity>'.


==== tests/cases/compiler/noExcessiveStackDepthError.ts (1 errors) ====
// Repro from #46631

interface FindOperator<T> {
foo: T;
}

type FindConditions<T> = {
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
};

function foo<Entity>() {
var x: FindConditions<any>;
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'FindConditions<any>', but here has type 'FindConditions<Entity>'.
!!! related TS6203 tests/cases/compiler/noExcessiveStackDepthError.ts:12:9: 'x' was also declared here.
}

34 changes: 34 additions & 0 deletions tests/baselines/reference/noExcessiveStackDepthError.js
@@ -0,0 +1,34 @@
//// [noExcessiveStackDepthError.ts]
// Repro from #46631

interface FindOperator<T> {
foo: T;
}

type FindConditions<T> = {
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
};

function foo<Entity>() {
var x: FindConditions<any>;
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
}


//// [noExcessiveStackDepthError.js]
"use strict";
// Repro from #46631
function foo() {
var x;
var x; // Excessive stack depth error not expected here
}


//// [noExcessiveStackDepthError.d.ts]
interface FindOperator<T> {
foo: T;
}
declare type FindConditions<T> = {
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
};
declare function foo<Entity>(): void;
43 changes: 43 additions & 0 deletions tests/baselines/reference/noExcessiveStackDepthError.symbols
@@ -0,0 +1,43 @@
=== tests/cases/compiler/noExcessiveStackDepthError.ts ===
// Repro from #46631

interface FindOperator<T> {
>FindOperator : Symbol(FindOperator, Decl(noExcessiveStackDepthError.ts, 0, 0))
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 2, 23))

foo: T;
>foo : Symbol(FindOperator.foo, Decl(noExcessiveStackDepthError.ts, 2, 27))
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 2, 23))
}

type FindConditions<T> = {
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))

[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5))
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))
>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5))
>FindOperator : Symbol(FindOperator, Decl(noExcessiveStackDepthError.ts, 0, 0))
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
>T : Symbol(T, Decl(noExcessiveStackDepthError.ts, 6, 20))
>P : Symbol(P, Decl(noExcessiveStackDepthError.ts, 7, 5))

};

function foo<Entity>() {
>foo : Symbol(foo, Decl(noExcessiveStackDepthError.ts, 8, 2))
>Entity : Symbol(Entity, Decl(noExcessiveStackDepthError.ts, 10, 13))

var x: FindConditions<any>;
>x : Symbol(x, Decl(noExcessiveStackDepthError.ts, 11, 7), Decl(noExcessiveStackDepthError.ts, 12, 7))
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))

var x: FindConditions<Entity>; // Excessive stack depth error not expected here
>x : Symbol(x, Decl(noExcessiveStackDepthError.ts, 11, 7), Decl(noExcessiveStackDepthError.ts, 12, 7))
>FindConditions : Symbol(FindConditions, Decl(noExcessiveStackDepthError.ts, 4, 1))
>Entity : Symbol(Entity, Decl(noExcessiveStackDepthError.ts, 10, 13))
}

24 changes: 24 additions & 0 deletions tests/baselines/reference/noExcessiveStackDepthError.types
@@ -0,0 +1,24 @@
=== tests/cases/compiler/noExcessiveStackDepthError.ts ===
// Repro from #46631

interface FindOperator<T> {
foo: T;
>foo : T
}

type FindConditions<T> = {
>FindConditions : FindConditions<T>

[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
};

function foo<Entity>() {
>foo : <Entity>() => void

var x: FindConditions<any>;
>x : FindConditions<any>

var x: FindConditions<Entity>; // Excessive stack depth error not expected here
>x : FindConditions<any>
}

17 changes: 17 additions & 0 deletions tests/cases/compiler/noExcessiveStackDepthError.ts
@@ -0,0 +1,17 @@
// @strict: true
// @declaration: true

// Repro from #46631

interface FindOperator<T> {
foo: T;
}

type FindConditions<T> = {
[P in keyof T]?: FindConditions<T[P]> | FindOperator<FindConditions<T[P]>>;
};

function foo<Entity>() {
var x: FindConditions<any>;
var x: FindConditions<Entity>; // Excessive stack depth error not expected here
}

0 comments on commit b8ee330

Please sign in to comment.