microsoft / microsoft/TypeScript

Excess-property check fires on a nested object literal that is later assigned to an annotated return type, where tsc 6.0 does not

Abierto
#63,815 2 comentarios 0 reacciones 1 asignado Reclamado por @ahejlsberg Ver en GitHub
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

## Steps to reproduce

`tsconfig.json`:

```json
{
"compilerOptions": {
"strict": true,
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"noEmit": true
}
}
```

`index.ts`:

```ts
interface TypeData {
ref?: string;
}

interface UsageData {
Type_Data?: Array;
Comments?: string;
}

interface EmailAddressData {
Email_Address: string;
Usage_Data?: Array;
}

declare function condition(): boolean;
declare function makeRef(s: string): string;
declare const emails: { value: string; isWork: boolean }[];

async function build(): Promise {
let emailAddressData;
if (condition()) {
const primary = emails[0];
emailAddressData = primary
? [
{
Email_Address: primary.value,
Usage_Data: [
{
attributes: { "wd:Public": false },
Type_Data: [
{
attributes: { "wd:Primary": true },
ref: makeRef("HOME"),
},
],
},
],
},
]
: [];
} else {
emailAddressData = emails.map((email) => ({
Email_Address: email.value,
Usage_Data: [
{
attributes: { "wd:Public": email.isWork },
Type_Data: [
{
attributes: { "wd:Primary": true },
ref: makeRef("HOME"),
},
],
},
],
}));
}
return emailAddressData;
}
build().then(console.log);
```

Tested with `@typescript/native-preview@beta` (`Version 7.0.0-dev.20260421.2`) and `typescript@6.0.3`.

The `attributes` field doesn't exist on `UsageData` or `TypeData` — but neither does it exist in any of the literals' contextual type at the *literal* expression sites, because both branches assign to the same untyped `let` and the contextual type only kicks in at the `return` statement.

## Behavior with `typescript@6.0`

Compiles cleanly (exit 0, no diagnostics). Excess-property checking does not fire on the nested literals because they are assigned to an untyped `let` variable and the contextual type only flows in at `return emailAddressData;` (where excess-prop checking is no longer "fresh").

## Behavior with `tsgo`

```
index.ts(29,17): error TS2353: Object literal may only specify known properties, and 'attributes' does not exist in type 'UsageData'.
```

Note that:

- Only the first `attributes: { "wd:Public": false }` (the `if (condition())` branch) is flagged. The matching `attributes` field in the `else` branch is **not** flagged.
- The inner `attributes: { "wd:Primary": true }` on `TypeData` is **not** flagged in either branch.

That asymmetric reporting suggests tsgo is propagating the contextual type back into one of the conditional branches (the `primary ? [...] : []` ternary that's inside the if-true branch) but not into `emails.map((email) => ({...}))` in the else branch. tsc treats both branches consistently.

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.