microsoft / microsoft/TypeScript
Rethinking relationships between `{}` type, `object`, and primitives
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
🔎 Search Terms
empty object type, {}, type safety violation, unsound
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about object types and structural typing
⏯ Playground Link
💻 Code
function takesObject(x: object) {
// This rightly is a TS error.
if (x === 0) {
console.error('This branch should be unreachable');
}
}
const o: {} = 0;
// But this isn't, and should be.
takesObject(o);
🙁 Actual behavior
No error on takesObject(o). {} can be assigned to type object, despite {} meaning "all nonnullish values", whereas object means only JS object types.
🙂 Expected behavior
Error on takesObject(o). {} is a wider type than object.
Additional information about the issue
This stems from a typescript-eslint investigation into making no-unnecessary-condition be more correct around possibly-falsy "object types", such as {}, or even { toFixed(): string} (to which number may be assigned). See https://github.com/typescript-eslint/typescript-eslint/pull/10378. This also relates to previous (controversial) conversations about whether to flag the {} type with the linter, see, e.g. https://github.com/typescript-eslint/typescript-eslint/issues/8700.
I'm wondering if this was simply an oversight in https://github.com/microsoft/TypeScript/pull/49119, which aimed to fix soundness holes with {}?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the assignability cases in the linked TypeScript Playground, then read the referenced TypeScript PR #49119 and the typescript-eslint investigation in PR #10378 for context on the {}/object boundary. The issue is complete when the reported takesObject(o) case produces the expected diagnostic and related primitive cases are checked for regressions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100