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

Offen
#63,815 2 Kommentare 0 Reaktionen 1 zugewiesene Person Auf GitHub ansehen

@ahejlsberg arbeitet bereits daran.

Seit 22.4.2026.

Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

## 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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.