具有类型要求的 Const 断言

Const assertion with type requirements

在 TypeScript 中,我有一个 class Foo 并想创建一个带有 const 断言的静态数组 bar,其中数组中的值仅限于 Foo 的键。该数组用作 func 中的类型,也用作运行时检查。

这是我目前的情况:(more details in TS Playground)

class Foo { a?: string; b?: string; c?: string }

const bar = ['a', 'b'] as const // need way for this to error if some 'd' which is not in Foo is added to the array

function func(arg: typeof bar[number]) { // TS should know arg is a keyof Foo as well
  // ...
  // some runtime usage of bar
}

我也试过:

const bar: (keyof Foo)[] = ['a', 'b']
// but arg is now typed as any keyof Food, and accepts any key, not just 'a' and 'b'

const bar: (keyof Foo)[] = ['a', 'b'] as const
// throws an Error: The type 'readonly ["a", "b"]' is 'readonly' and cannot be assigned to the mutable type '(keyof Foo)[]

Pick 获取一个对象版本,所以这不起作用。

这可能吗?

这样的怎么样?

class Foo { a?: string; b?: string; c?: string }

function getArgs<T extends ReadonlyArray<keyof Foo>>(args: T): T {
  return args
}

const bar1 = getArgs(['a', 'b', 'c', 'd'] as const) // error

function func1(arg: typeof bar1[number]) {
  // ...
  const f = new Foo()
  console.log('bar', bar1)
  console.log('f[arg]', f[arg])
}

const bar2 = getArgs(['a', 'b'] as const)

function func2(arg: typeof bar2[number]) {
  // ...
  const f = new Foo()
  console.log('bar', bar1)
  console.log('f[arg]', f[arg])
}

func2('c') // error