denoland / deno_lint

Blazing fast linter for JavaScript and TypeScript written in Rust
https://lint.deno.land/
MIT License
1.53k stars 172 forks source link

ban-types gives misleading/wrong suggestion for empty object on generic bounds #1260

Open lucasavila00 opened 6 months ago

lucasavila00 commented 6 months ago

I had code that relied on the empty object having no keys. Accepting the linter suggestion broke this.

type X = {}
// `{}` doesn't mean an empty object, but means any types other than `null` and `undefined`
// If you want a type that means "empty object", use `Record<string | number | symbol, never>` instead
// deno-lint(ban-types)
type Y = keyof X // never

type X2 = Record<string | number | symbol, never>
type Y2 = keyof X2 // string | number | symbol

type X3 = Record<never,never>
type Y3 = keyof X3 // never

I ended up using Record<never, never>.

In my case, I was using this as a generic bound

const x = <T extends Record<string,string> = {}>(a: T):T => a

Should the message change if the empty record is a generic bound?