TypeScript函数,该函数采用没有某些键的对象

Ant*_*deo 2 typescript

尝试创建一个带有单个参数对象的函数,该对象必须没有一组键,而无需使人们手动指定类型。我试图以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: ''})
Run Code Online (Sandbox Code Playgroud)

您将如何解决这个问题?

jca*_*alz 5

我想我首先会尝试远离泛型和条件类型,并执行以下操作:

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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,ValidAttributes是一个通用的字符串值字典,但是ReservedAttributes列出的键是type的never可选属性(允许丢失可选属性,并且不允许never真正存在type的属性,因此type的可选属性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
Run Code Online (Sandbox Code Playgroud)

但是它更复杂并且可以达到类似的结果。希望能有所帮助;祝好运!