Skip to content

Declaration Order Affects Type Checking #61806

Closed as not planned
Closed as not planned
@rishipal

Description

@rishipal

🔎 Search Terms

"declaration order", "sequence of interface declaration", "declaration sequence", "inconsistent type checking"

🕗 Version & Regression Information

This seems to be happening after v4.8.

The TypeScript compiler exhibits inconsistent type checking behavior when the order in which the interfaces are declared is changed. Specifically, changing the order of interface declarations can enable or disable expected type errors, suggesting a bug in how the compiler handles type resolution and caching.

Steps to Reproduce:

Example 1: No type error

Playground - https://www.typescriptlang.org/play/?#code/FDAuE8AcFMAIDkCuBbARtATgJQPYHdYBeWAOxXQwG0BdAbjCjgGVQMBLEgc1wOIGdWHTjXrAOoTADMAhgGM4SNJgDqGaZBgZYAb2CxY0jBgBcCcpgCCR6eBHAAviHFS5C8xitrwOvbABu0gA2iNCmihQ8do7OGDLysCzsXKrqmj76hiYJglyeNlFOJBKxrtlJnHneuvoBwaFlQpF0DiDAkogksqBsOCSwkgCMABQAlOmwsr0CpO4pGphhs2rzWsTamaY09vT6APS7sJDSfHzQfAA0sKiIoLB8ABY4iIEAJv3SbIG+kyTTAuVzNLEMhKDCAzAGPgNZLLTT0RxtDpdHp9SQAJlG4x+0xBFEqi1BlSIOlqIU21G2vn2h2OpwuVxud0ezzeMk+3ymt3+QiJwPcROO0Iq1nAtFgLRA7U63V6-QAzJjqhNOTNQTwCRF8MS7HsDkcTmdLtcuczXu92fpsVyctwtXy1VrBYlGvgxRKgA

type NumberRow = number[];
type StringRow = string[];

interface NumberWrapper {
  arr: NumberArray[];
}

interface NumberArray {
  value: NumberRow[];
}
interface StringWrapper {
  arr: StringArray[];
}

interface StringArray {
  value: StringRow[];
}


function f1() {
  const numberWrapper: NumberWrapper = {arr: []};
  // passes, but should fail
  const stringWrapper = numberWrapper as StringWrapper;
}

function f2() {
  const numberArray: NumberArray = {value: []};
  // passes, but should fail
  const stringArray = numberArray as StringArray; 
}


function f3() {
  const numberRow: NumberRow = [];
  // passes, but should fail
  const stringRow = numberRow as StringRow; 
}

Example 2: Type Error

Changing the order of interface declarations, it now generates the type errors and fails -

Playground - https://www.typescriptlang.org/play/?#code/FDAuE8AcFMAIDkCuBbARtATgJQPYHdYBeWAOxXQwG0BdAbjCjgGVQMBLEgc1wOIGdWHTjXrAOoTADMAhgGM4SNJgCCGDNPCwA3sFiwAbtIA2iaAC4E5TDxHAAviHFS5zQV1XrNOvYZPnYLOxcNnT2IGIkEhgy8pZKGADq6pAwGNq6sNJqFooUHhq2DhFRMa5BnEnSKZjpelkYFoFC+eCF4ZKIJLKgbDgksJIAjAAUAJTpGbJ9AqRWicmpOXOV1WnEWvUWNHb0egD0ewPSbEZ8mWfQAB4w3dAAJpPToLAC5SupRLPx7zXSZ01cH4YehFDpdHp9AYAJjGtVgUxIMzI8RaSxRag0ny0vlMW2oOwyByOJzOf1gVxuEgeegRM1ezQxmmIyLyjPOATcnBaIPanW6vX6kgAzLDvPCnl8KDw0VL8J9bPtDjISeyKdBbtTxYjnvTgnLmXMeOyAdx8LRYGFgEA

type NumberRow = number[];
type StringRow = string[];

interface NumberArray {
 value: NumberRow[];
}

interface StringArray {
 value: StringRow[];
}

interface NumberWrapper {
 arr: NumberArray[];
}

interface StringWrapper {
 arr: StringArray[];
}


function f1() {
 const numberWrapper: NumberWrapper = {arr: []};
 // fails as expected
 const stringWrapper = numberWrapper as StringWrapper;
}

function f2() {
 const numberArray: NumberArray = {value: []};
 // fails as expected
 const stringArray = numberArray as StringArray;
}

function f3() {
 const numberRow: NumberRow = [];
 // fails as expected
 const stringRow = numberRow as StringRow;
}

Impact:
This bug can lead to undetected type errors, making it difficult to rely on TypeScript's type system for correctness.

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/FDAuE8AcFMAIDkCuBbARtATgJQPYHdYBeWAOxXQwG0BdAbjCjgGVQMBLEgc1wOIGdWHTjXrAOoTADMAhgGM4SNJgDqGaZBgZYAb2CxY0jBgBcCcpgCCR6eBHAAviHFS5C8xitrwOvbABu0gA2iNCmihQ8do7OGDLysCzsXKrqmj76hiYJglyeNlFOJBKxrtlJnHneuvoBwaFlQpF0DiDAkogksqBsOCSwkgCMABQAlOmwsr0CpO4pGphhs2rzWsTamaY09vT6APS7sJDSfHzQfAA0sKiIoLB8ABY4iIEAJv3SbIG+kyTTAuVzNLEMhKDCAzAGPgNZLLTT0RxtDpdHp9SQAJlG4x+0xBFEqi1BlSIOlqIU21G2vn2h2OpwuVxud0ezzeMk+3ymt3+QiJwPcROO0Iq1nAtFgLRA7U63V6-QAzJjqhNOTNQTwCRF8MS7HsDkcTmdLtcuczXu92fpsVyctwtXy1VrBYlGvgxRKgA

🙁 Actual behavior

The TypeScript compiler's behavior depends on the declaration order of the interfaces. When NumberArray and StringArray are declared after NumberWrapper and StringWrapper respectively, the compiler does not report the type error. When the declaration order is changed, the compiler correctly reports the error.

🙂 Expected behavior

The TypeScript compiler should consistently report a type error regardless of the sequence of interface declarations.

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions