试着创建一个函数,该函数接受一个参数对象,该对象不能有一些键集,而不是让人们手动指定类型。我试图以某种方式利用 never
,但我陷入了试图理解推理如何适用于接受具有泛型参数的类型的函数参数的过程。
interface ReservedAttributes {
someKey: string
}
// evaluates to never if the type has a key that intersects
// with the keys in ReservedAttributes
type ValidAttributes<T> = keyof T extends Exclude<keyof T, keyof ReservedAttributes> ? T : never
// This is correctly a never, but it doesn't address this problem
type Test = ValidAttributes<{someKey : string}>
// This doesn't work because the function argument ends
// up being inferred as { [name: string] : string}
function foo1<K extends { [name: string] : string}>(attributes: ValidAttributes<K>) {
// ...
}
foo1({a: 'hi', someKey: ''})
// Roughly equivalent to the above
function foo2< K extends { [name: string] : string}, V extends ValidAttributes<K> >(attributes: V) {
// ...
}
// This one allows V to correctly evaluate to never,
// but I'm not sure how to leverage that
function foo3< K extends { [name: string] : string}, V extends ValidAttributes<K> >(attributes: K) {
// ...
}
foo3({a: 'hi', someKey: ''})
你会如何解决这个问题?
最佳答案
我想我会先尝试远离泛型和条件类型,然后做这样的事情:
type ValidAttributes = Record<string, string> &
Partial<Record<keyof ReservedAttributes, never>>;
declare function foo(attributes: ValidAttributes): void;
foo({ a: 'hi' }); // okay
foo({ a: 'hi', someKey: '' }); // error, someKey
在这种情况下,ValidAttributes
是一个通用的字符串值字典,但是 ReservedAttributes
中的键被列为 never
类型的可选属性(允许缺少可选属性,并且类型 never
的属性实际上不允许存在,因此 never
类型的可选属性或多或少是必须的缺少。)这对你有用吗?
如果您需要在泛型约束中使用条件类型,可以这样做:
type Attributes<K extends keyof any> = {
[P in K]: P extends keyof ReservedAttributes ? never: string
};
declare function foo<T>(attributes: T & Attributes<keyof T>): void;
foo({ a: 'hi' }); // okay
foo({ a: 'hi', someKey: '' }) // error
但它更复杂并且达到类似的结果。希望有所帮助;祝你好运!
关于采用没有特定键的对象的 TypeScript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52618362/