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

Đang mở
#63,815 2 bình luận 0 reaction 1 người được giao Được @ahejlsberg nhận Xem trên GitHub
Ngôn ngữ chính
Go
Star
111k
Fork
14.3k
Merge trung bình
2 ngày 4 giờ
Pull request đã merge (30 ngày)
132

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.