我正在开发一个 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 的类型系统来实现这一点?
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