diff --git a/source/except.d.ts b/source/except.d.ts index ad542580c..5c1e249c5 100644 --- a/source/except.d.ts +++ b/source/except.d.ts @@ -1,3 +1,34 @@ +import {IsEqual} from './internal'; + +/** +Filter out keys from an object. + +Returns `never` if `Exclude` is strictly equal to `Key`. +Returns `never` if `Key` extends `Exclude`. +Returns `Key` otherwise. + +@example +``` +type Filtered = Filter<'foo', 'foo'>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', string>; +//=> never +``` + +@example +``` +type Filtered = Filter<'bar', 'foo'>; +//=> 'bar' +``` + +@see {Except} +*/ +type Filter = IsEqual extends true ? never : (KeyType extends ExcludeType ? never : KeyType); + /** Create a type from an object type without certain keys. @@ -21,4 +52,6 @@ type FooWithoutA = Except; @category Utilities */ -export type Except = Pick>; +export type Except = { + [KeyType in keyof ObjectType as Filter]: ObjectType[KeyType]; +}; diff --git a/source/includes.d.ts b/source/includes.d.ts index 669ff91b8..c429905e2 100644 --- a/source/includes.d.ts +++ b/source/includes.d.ts @@ -1,13 +1,4 @@ -/** -Returns a boolean for whether the two given types are equal. - -@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 -*/ -type IsEqual = - (() => G extends T ? 1 : 2) extends - (() => G extends U ? 1 : 2) - ? true - : false; +import {IsEqual} from './internal'; /** Returns a boolean for whether the given array includes the given item. diff --git a/source/internal.d.ts b/source/internal.d.ts new file mode 100644 index 000000000..573019003 --- /dev/null +++ b/source/internal.d.ts @@ -0,0 +1,11 @@ +/** +Returns a boolean for whether the two given types are equal. + +@link https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 +@link https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796 +*/ +export type IsEqual = + (() => G extends T ? 1 : 2) extends + (() => G extends U ? 1 : 2) + ? true + : false; diff --git a/test-d/except.ts b/test-d/except.ts index c570c3eb2..47ae0c89f 100644 --- a/test-d/except.ts +++ b/test-d/except.ts @@ -3,3 +3,14 @@ import {Except} from '../index'; declare const except: Except<{a: number; b: string}, 'b'>; expectType<{a: number}>(except); + +// Generic properties +interface Example { + [key: string]: unknown; + foo: number; + bar: string; +} + +const test: Except = {foo: 123, bar: 'asdf'}; +expectType(test.foo); +expectType(test.bar);