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

オープン
#63,815 コメント 2 件 リアクション 0 件 担当者 1 名 GitHub で見る

@ahejlsberg がすでに取り組んでいます。

2026年4月22日 から。

主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

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

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。