鍍金池/ 問答/HTML/ 如何在typescript中定義一個Omit<Source, Exclud

如何在typescript中定義一個Omit<Source, Exclude extends keyof Source>泛型類型

如何定義一個Omit<SourceType, ExcludeProps extends keyof SourceType>泛型類型, 使得

  1. 結果類型中沒有鍵值在ExcludeProps中的屬性
  2. 結果類型中有的屬性, 其optional屬性與SourceType一致

我有幾個嘗試如下

// 測試用的一些工具
const test: <T>(t: T) => any = null
type SourceType = {
    a: number
    b?: string
    c: boolean
}
type ExcludeProps = "c"
type TargetType = {
    a: number
    b?: string
}
const testValue: TargetType = null

type Omit<A, B extends keyof A> = {
    [K in keyof A]: A[K]
} & {
    [K in B]: never
}

test<Omit<SourceType, ExcludeProps>>(testValue)

這種會在testValue報如下錯誤

Argument of type 'TargetType' is not assignable to parameter of type 'Omit<SourceType, "c">'.
  Type 'TargetType' is not assignable to type '{ a: number; b?: string; c: boolean; }'.
    Property 'c' is missing in type 'TargetType'.

type Diff<A extends string, B extends string> = ({
  [K in A]: K
} & {
  [K in B]: never
} & {
  [K: string]: never  
})[A]
type Omit<A, B extends keyof A> = {
  [K in Diff<keyof A, B>]: A[K]
}

test<Omit<SourceType, ExcludeProps>>(testValue)

這種會在testValue報如下錯誤

Argument of type 'TargetType' is not assignable to parameter of type 'Omit<SourceType, "c">'.
  Property 'b' is optional in type 'TargetType' but required in type 'Omit<SourceType, "c">'.


// 需要typescript>=2.8
type Omit<A, B extends keyof A> = {
    [K in keyof A]: K extends B ? never : A[K]
}

test<Omit<SourceType, ExcludeProps>>(testValue)

這種會在testValue報如下錯誤

Argument of type 'TargetType' is not assignable to parameter of type 'Omit<SourceType, "c">'.
  Property 'c' is missing in type 'TargetType'.
回答
編輯回答
舊螢火

可嘗試:


type Omit<A, B extends keyof A> = Pick<A, {
  [K in keyof A]: K extends B ? never : K
}[keyof A]>

或者:


type Omit<A, B extends keyof A> = Pick<A, ({
  [K in keyof A]: K
} & {
  [K in B]: never
})[keyof A]>
2018年5月13日 11:15