具有禁止属性名称的打字稿类型

asn*_*aeb 7 typescript

我需要创建一个排除某些文字类型并接受所有其他字符串的类型。我试过这个:

type ExcludedKeys = "a"|"b"

type MyType = {
    [K in Exclude<string,ExcludedKeys>]: any
}

const obj: MyType = {
    a: 0, // No Error
    b: 1 // No Error
}
Run Code Online (Sandbox Code Playgroud)

但很快我发现,这Exclude<string,ExcludedKeys>只是简单地评估string,并且不可能以这种方式做到这一点。然后我尝试了这种方法:

type ExcludedKeys = "a"|"b"

type MyType<T> = keyof T extends ExcludedKeys ? never : {
    [K in keyof T]: T[K]
} 

declare class Obj {
    a: number
    b: number
    c: number // Adding this removes the wanted error.
}

const obj: MyType<Obj> = {
    a: 0, // No Error
    b: 1, // No Error
    c: 3
}
Run Code Online (Sandbox Code Playgroud)

但这仅当 的成员ExcludedKeys是对象的唯一道具时才有效。

TS 游乐场链接

我需要的

如前所述,否定那些可分配给一组字符串的属性名称的类型

type ExcludedKeys = "a"|"b"

const obj = {
    a: 0, // Error Here
    b: 1, // Error Here
    c: 3
}
Run Code Online (Sandbox Code Playgroud)

编辑

尽管我没有提及它是为了简化上下文,正如jsejcksn 的答案指出的那样,我需要这种类型来保留给定类模型中的类型信息。话虽如此,莱普施的答案仍然是被接受的答案,因为它以最简短和简单的方式满足了我的要求。不管怎样,我想分享一下我如何改变这种方法来满足我的需求。

type ExcludedKeys = "a"|"b"

const obj = {
    a: 0, // Error Here
    b: 1, // Error Here
    c: 3
}
Run Code Online (Sandbox Code Playgroud)

游乐场链接

lep*_*sch 5

你快到了。尝试这个:

type ExcludedKeys = "a"|"b"

type MyType1 = {
    [key: string]: any
} & {
    [K in ExcludedKeys]: never
}

const obj1: MyType1 = {
    a: 0, // Error
    b: 1, // Error
    c: 3, // No Error
}
Run Code Online (Sandbox Code Playgroud)