Typescript -- 定义 "Empty object" 类型

Typescript -- Define "Empty object" type

基于此posthttps://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492

我输入了相同的示例,但对于“d”和“e”,我的 .ts 文件中没有出现任何错误... 这 2 个缺失的错误是否与某些 TS 配置有关?

export type EmptyObject = Record<string, never>

const a: EmptyObject = { a: 1 }    // I get error - as expected
const b: EmptyObject = 1           // I get error - as expected
const c: EmptyObject = () => {}    // I get error - as expected

const d: EmptyObject = null        // NO ERROR, but it SHOULD show ERROR message
const e: EmptyObject = undefined   // NO ERROR, but it SHOULD show ERROR message

const f: EmptyObject = {} // I get NO ERROR - as expected

这不是最好的解决方案,因为您应该将其包装到 func 中。不知道它是否适合你。

type Keys<T> = keyof T
type Values<T> = T[keyof T]
type Empty = {} & { __tag: 'empty' };

type IsEmpty<T> =
  Keys<T> extends never
  ? Values<T> extends never
  ? Empty : never
  : never

const empty = <T extends Record<string, never>>(arg: T) => arg as IsEmpty<T> extends Empty ? T : never

const a: Empty = empty({ a: 1 })    // I get error - as expected
const b: Empty = empty(1)           // I get error - as expected
const c: EmptyObject = empty(() => { })    // I get error - as expected

const d: Empty = empty(null)        //  ERROR, but it SHOULD show ERROR message
const e: Empty = empty(undefined)   //  ERROR, but it SHOULD show ERROR message

const f: Empty = ({}) // NO ERROR - as expected

Typescript 有一个 --strictNullChecks 标志:

In strict null checking mode, the null and undefined values are not in the domain of every type and are only assignable to themselves and any (the one exception being that undefined is also assignable to void).

您似乎没有启用此功能,这意味着 null 和 undefined 可以是任何类型。由于这是明智的选择,连同其他各种严格的标志,typescript 有一个 --strict 标志,可以启用 --strictNullChecks 和其他标志。

Read more about compiler options here.

此标志在 typescript playground 的“TS 配置”部分中也可见: