如何在此 TypeScript 方法中强制执行严格的参数类型?

问题描述 投票:0回答:1

我正在开发一个 TypeScript 类,我希望方法

test()
根据我之前使用
add()
方法添加的设置严格验证其参数。但是,我不确定如何实现这一目标。这是我的代码:

class Test {
  private settings: { [name: string]: any[] } = {}

  add(name: string, ...args: any[]) {
    this.settings[name] = args
    return this
  }

  test<T extends keyof typeof this.settings>(name: T, ...args: typeof this.settings[T]) {
    console.log(this.settings[name])
  }
}

const test = new Test()

test.add("a", 1, "test", 3)
test.add("b", 1)
test.add("c", "test")

test.test("a", 1, "test", 3) // Works fine
test.test("b", 1)           // Works fine
test.test("c", "test")      // Works fine

test.test("a", 13) // <-- This should throw a type error, but it doesn't

我希望

test()
方法强制传递的参数与
name
方法中给定
add()
设置的参数完全匹配。例如:

  • test("a", 1, "test", 3)
    应该是有效的。
  • test("a", 13)
    应该抛出类型错误,因为
    13
    与之前为
    "a"
    设置的参数不匹配。

目前,TypeScript 允许我调用

test("a", 13)
,而不会抛出类型错误,即使参数与为 "a"
 存储的内容不匹配。

如何使

test()

 方法根据 
add()
 方法中设置的内容严格验证其参数?有没有办法使用 TypeScript 的类型系统来实现这一点?

typescript
1个回答
0
投票
你可以做这样的事情(需要更多的工作来避免任何/as)或者只是将所有测试传递到构造函数中:

游乐场

class Test<T extends Record<string, any[]> = {}> { private settings = {} as T; add<N extends string, const A extends any[]>(name: N, ...args: A) { (this.settings as any)[name] = args return this as unknown as Test<T & {[k in N]: A}>; } test<K extends keyof T>(name: K, ...args: T[K]) { console.log(this.settings[name]) } } const test = new Test() .add("a", 1, "test", 3) .add("b", 1) .add("c", "test") test.test("a", 1, "test", 3) // Works fine test.test("b", 1) // Works fine test.test("c", "test") // Works fine test.test("a", 13) // <-- This should throw a type error, but it doesn't
    
© www.soinside.com 2019 - 2024. All rights reserved.