Open
Description
Bug Report
Typescript does not allow the assignment of Source4
to Target4
which is expected because they are incompatible. After 3 or more levels of nested array properties this error is not detected anymore. Even the errors on the nested types may disappear depending on the order of the assignments.
Note: every type is explicitly named and there are no cycles.
(This actually caused problems in our production codebase)
🔎 Search Terms
nested array assignment, undetected illegal assignment of nested array types, undetected illegal assignment, illegal assignment
🕗 Version & Regression Information
- In versions before 4.5.3: limit of nested array levels is 5 instead of 3
- This changed between versions 4.4.4 and 4.5.3 (to 3 levels)
- PRs:
- bisect: 🤖 Pick PR #46599 (Improve recursion depth checks) into release-4.5 #46974 (thank you @pyBlob for bisect)
- main: Improve recursion depth checks #46599
- maybe:
isDeeplyNestedType
maxDepth check?
- maybe:
⏯ Playground Link
Playground link with relevant code
💻 Code
type Source1 = { array: Source2[] };
type Source2 = { array: Source3[] };
type Source3 = { array: Source4[] };
type Source4 = {};
// same as Source types but with "someNewProperty"
type Target1 = {
array: Target2[];
// someNewProperty: string // error in target1 assignment as expected if enabled
};
type Target2 = {
array: Target3[];
// someNewProperty: string // error in target1 assignment as expected if enabled
};
type Target3 = {
array: Target4[];
// someNewProperty: string // error in target1 assignment as expected if enabled
};
type Target4 = {
someNewProperty: string; // not existing in Source4 => no error in target1 assignment
};
declare const source1: Source1;
declare const source2: Source2;
declare const source3: Source3;
declare const source4: Source4;
// this should not compile:
const target1: Target1 = source1; // comment this line to get errors in target2, target3 assignments or move this line after target2 assignment
// this should not compile:
const target2: Target2 = source2; // error if target1 assignment is commented or after this assignment
// this should not compile:
const target3: Target3 = source3; // error if target1 assignment is commented or after target2 assignment
// does not compile:
const target4: Target4 = source4; // error as expected
/*
PS:
- same (wrong) behavior with interfaces and classes
*/
🙁 Actual behavior
Source1
is assignable toTarget1
Source2
is assignable toTarget2
Source3
is assignable toTarget3
- Reordering of assignments impact type checking
- If
source1
assignment is skipped or moved aftersource2
assignment the expected errors show
- If
🙂 Expected behavior
Source1
is not assignable toTarget1
Type 'Source1' is not assignable to type 'Target1'.
Types of property 'array' are incompatible.
Type 'Source2[]' is not assignable to type 'Target2[]'.
Type 'Source2' is not assignable to type 'Target2'.
Types of property 'array' are incompatible.
Type 'Source3[]' is not assignable to type 'Target3[]'.
Type 'Source3' is not assignable to type 'Target3'.
Types of property 'array' are incompatible.
Type 'Source4[]' is not assignable to type 'Target4[]'.
Property 'someNewProperty' is missing in type 'Source4' but required in type 'Target4'.
- Since
Source1
is a fixed/static tree (without any self references) I expect the error to be found by the compiler. - Reordering of assignments do not impact type checking results