Skip to content

Excess and common property checks don't work correctly with NoInferΒ #57697

Closed
@Andarist

Description

@Andarist

πŸ”Ž Search Terms

epc excess common properties weak type noinfer

πŸ•— Version & Regression Information

  • I was unable to test this on prior versions because NoInfer was introduced in 5.4

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.5.0-dev.20240308#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXwxAGcMBGAHgBV4QAPQ1YI+Ab3loC54SYtUBzeAF8AfAAoAUPHhQulADRT4AIy4A5HAElUiEDCoj4AH3hixASngBeQxu279lEecXmuANxxZgAbgkTCElIxNk54ACJEHBxw4XlWdi5w5VhYoXMfeAB6LJl8PjAcGDhMGgAHMBpiooDiMhDEiKiYuISw5NT4gE8uABYAJmEM7NyQCqqYIpVkDHg8GXgAd0mBeDLJsr0MLv9QSFgEFHRsecCMfqoaehBGZlCuHj5BUUlpWXgFJVV4Ox09A2MPy0f30Fmshicrg8Xl8-jO-Qa7WaaXi9wiKRgaQytRICLRkWiKLaSQx4W6fUG6UyOW4AAscMgIMB4LSoO4EFB8GNKnpJjBduBoHAkGhMLh8GcAMyXOgMJjE7gYXirF5Kd6faTfX4OS4mMyWGwfcwiKHwTzePwSGkYelEBCLIoAayQfBAOIwksRSWRrXxpKGfilXqahN9jQ6mPJ8AGAYF+2FhVQJDWsGwUAgAHllAArUhcAAKqaw6fIbHeaEdqBwi1QmW+FarNeEIj8eyFCETybKRfTWez-QLPYgpfgYC4DertfgwHHqErk+brcFB1HeGTRBwAFsQH28wrHirLW2V0cxac6r0DGJ1fEtcCdU54AAyBLrHBlAD8s-nTfS0ItcIXmI3YwGmmY5qQ8Qbtuu7DDSRD0oyzJwGURSzFWq6bpu8xvmUzC8jUEjHsKp4nBKdQAKxUJBHz9OIapyJBXxyP0ijSGOQL2P8lCkIYL7atxdGmuasLuhRwFDru8QgWBfasdwW47hBcG5AhDJMvAKFofAGGFFhOEbPh1T8kRy4kaKZEEHUABs1HxJQdHXoxt4sfEHECY4pDPrRzj-qJZzWRJoHFuBubSZJObydBSm5ipBC0lgzB4PaTpJY6EhAA

πŸ’» Code

declare function test1<T extends { x: string }>(
  a: T,
  b: NoInfer<T> | (() => NoInfer<T>),
): void;

test1({ x: "foo" }, { x: "bar" }); // an incorrect epc error
test1({ x: "foo" }, { x: "bar", y: 42 }); // epc error but on a wrong property

declare function test2<T extends { x: string }>(
  a: T,
  b: NoInfer<T> | NoInfer<() => T>,
): void;

test2({ x: "foo" }, { x: "bar" });
test2({ x: "foo" }, { x: "bar", y: 42 }); // should have an epc error

declare function test3<T extends { x: string }>(
  a: T,
  b: NoInfer<T | (() => T)>,
): void;

// those work fine
test3({ x: "foo" }, { x: "bar" });
test3({ x: "foo" }, { x: "bar", y: 42 });

declare const partialObj1: Partial<{ a: unknown; b: unknown }>;
declare const partialObj2: Partial<{ c: unknown; d: unknown }>;
declare const someObj1: { x: string };

declare function test4<T>(a: T, b: NoInfer<T> & { prop?: unknown }): void;

test4(partialObj1, someObj1); // should report no common props error

declare function test5<T1, T2>(
  a: T1,
  b: T2,
  c: NoInfer<T1> & NoInfer<T2>,
): void;

test5(partialObj1, partialObj2, someObj1); // should report no common props error

declare function test6<T1, T2>(a: T1, b: T2, c: NoInfer<T1 & T2>): void;

test6(partialObj1, partialObj2, someObj1); // this one works ok

πŸ™ Actual behavior

Excess property check doesn't work properly when union members are wrapped by NoInfer individually. Similarly common properties check doesn't work properly with intersections when its members are wrapped by NoInfer individually

πŸ™‚ Expected behavior

I've annotated the playground with expected results where appropriate

Additional information about the issue

this open PR fixes it: #57673

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions