microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.85k stars 12.46k forks source link

Pick utility - error on excess values #56830

Closed nitzcard closed 10 months ago

nitzcard commented 10 months ago

Using Pick on a function argument and then giving it a defined variable with excess properties do not give error like if I write it inline.

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play?ssl=22&ssc=1&pln=1&pc=1#code/FASwdgLgpgTgZgQwMZQAQEFUG9itQgBwIBsoAuVMAVwFsAjWAbl1ToTHYQuvqeAF9gwCAE8CaAAogkAaygATVAF5UU2QB50AGlQByNhw66AfM2BwqYJBBAB7MKiQALKLIAUCGAHMAzhTVy8gCU2ILAAPThqAC0sXHxCYlJySkJwEj2PhCoAG7K2KycHBQAjDqEJOSoJaj8zM6uMm5YhYZc1eVEpKW1IZGoAOq2MDI++GPg0GDyCuku7jkhqP0+TrZUxIpeIDlo7KiwMMOoxCBy+HS2uxFRqXf3D-FC-UMjYwgTkFDTsxlgWfh-NJAvkcHgKt09HRiAhdFoWMN2F4qgAOeFhFgsIA

💻 Code


interface A {
  apple: number;
  banana: number;
}

type Picked = Pick<A, 'banana'>;

function check(args: Picked) {}

// --------------------------------------------------
const v = { banana: 1, apple: 1 };
check({ banana: 1, apple: 1 }) // Works as intended
check(v)  // should give an error like above
// --------------------------------------------------

// Works as intended
const a: Picked = {
  apple: 'bla',
  orange: 8,
}

🙁 Actual behavior

check(v) do not raise an error

🙂 Expected behavior

check(v) should raise an error

Additional information about the issue

No response

Andarist commented 10 months ago

This is working as intended. Object types are not sealed in TypeScript and the excess property check is more like a lint rule than a strong type error. See the docs: https://www.typescriptlang.org/docs/handbook/2/objects.html#excess-property-checks

nmain commented 10 months ago

Pick<...> has no impact here and the results are exactly the same if you write:

type Picked = { banana: number };
fatcerberus commented 10 months ago

There’s a reason the error message specifies “Object literal can only specify known properties”; v is not an object literal. You’d need #12936 to enforce this across the board.

typescript-bot commented 10 months ago

This issue has been marked as "Working as Intended" and has seen no recent activity. It has been automatically closed for house-keeping purposes.