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
Related issues
Metadata
Metadata
Assignees
Labels
A bug in TypeScriptA bug in TypeScriptIt's likely this is extremely difficult to fix without making something else much, much worseIt's likely this is extremely difficult to fix without making something else much, much worseYou can do thisYou can do this