Skip to content

as type assertion fails for ReadonlyArray<T> but succeeds for T[] with identical object literalΒ #62910

@raymondwang

Description

@raymondwang

πŸ”Ž Search Terms

  • ReadonlyArray assertion
  • readonly array type cast
  • sufficiently overlaps readonly

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried (tested in 3.5.1, 5.9.3, and nightly)

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.9.3#code/JYOwLgpgTgZghgYwgAgJKQLbIN4ChkHJQRwAmA9iADYCeywpAXMgM5hSgDmA3PocWUq1kVOACMIVZmw4hOyAD7IQAVypVeAX1y5QkWIhQBZFWHFUI6CBhY4+BARWp1gmFsysYA2gF1FytQ1cbV1waHgkZAAlEidaT1s8QiJYoRc3ZhjBZwBBKCg4GgAeTwA+f1V1LR0ESjZkDHIEAGsTMzELBOQAXjtk12t3ZC97ZL6xiYZmAHIARmmAGlHkzSXknyXNZDhbNvNLN15cWpB6xpasuJou3qTCAZtmEYmCO5f7pmRpgCZF5cJVqMNsFtrZLmkEtwgA

πŸ’» Code

interface Item {
    readonly id: string;
    readonly label: string | null;
}

interface MutableItems {
    readonly items: Item[] | null;
}

interface ReadonlyItems {
    readonly items: ReadonlyArray<Item> | null;
}

const mockMutableItems = {
    items: [
        {
            id: '1',
        },
    ],
} as MutableItems;

const mockReadonlyItems = {
    items: [
        {
            id: '2',
        },
    ],
} as ReadonlyItems;

πŸ™ Actual behavior

mockReadonlyItems produces error TS2352:

Conversion of type '{ items: { id: string; }[]; }' to type 'ReadonlyItems' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Types of property 'items' are incompatible.
    Type '{ id: string; }[]' is not comparable to type 'readonly Item[]'.
      Property 'label' is missing in type '{ id: string; }' but required in type 'Item'.

πŸ™‚ Expected behavior

Both assertions should behave consistently. Since the mutable Item[] version allows the assertion (correctly recognizing that as is an intentional type override), the ReadonlyArray<Item> version should also allow it.

Additional information about the issue

Other observations:

  • as const satisfies errors consistently, which seems good
  • Omitting items from mockReadonlyItems removes the associated type error, suggesting that the issue is specifically when trying to assert on a defined ReadonlyArray

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions