fix(typescript-types): Handle union types when filtering
This commit is contained in:
@@ -29,15 +29,17 @@ type KeyPathOf<
|
|||||||
? PrefixIfNot<Options['leavesOnly'], Parent, KeyPathsOfStringKeys<Obj, Options, Filter, Parent>>
|
? PrefixIfNot<Options['leavesOnly'], Parent, KeyPathsOfStringKeys<Obj, Options, Filter, Parent>>
|
||||||
: Parent
|
: Parent
|
||||||
|
|
||||||
|
type DoesNotMatchFilter<T, Filter> = T extends Filter ? false : true
|
||||||
|
|
||||||
type KeyPathsOfStringKeys<
|
type KeyPathsOfStringKeys<
|
||||||
Obj extends object,
|
Obj extends object,
|
||||||
Options extends Required<KeyPaths_Options>,
|
Options extends Required<KeyPaths_Options>,
|
||||||
Filter = never,
|
Filter = never,
|
||||||
Parent extends string = ''
|
Parent extends string = ''
|
||||||
> = {
|
> = {
|
||||||
[Key in keyof Obj & string]: Obj[Key] extends Filter
|
[Key in keyof Obj & string]: DoesNotMatchFilter<Obj[Key], Filter> extends true
|
||||||
? never
|
? KeyPathOf<Obj[Key], Options, GetPrefixedKey<Parent, Key, Options['separator']>, Filter>
|
||||||
: KeyPathOf<Obj[Key], Options, GetPrefixedKey<Parent, Key, Options['separator']>, Filter>
|
: never
|
||||||
}[keyof Obj & string]
|
}[keyof Obj & string]
|
||||||
|
|
||||||
export type KeyPaths<
|
export type KeyPaths<
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { expect } from 'tstyche'
|
|||||||
interface ExampleObject {
|
interface ExampleObject {
|
||||||
nullvalue: null
|
nullvalue: null
|
||||||
simplevalue: string
|
simplevalue: string
|
||||||
|
optionalKey?: string
|
||||||
config: {
|
config: {
|
||||||
nullvalue: null
|
nullvalue: null
|
||||||
simplevalue: string
|
simplevalue: string
|
||||||
@@ -12,19 +13,20 @@ interface ExampleObject {
|
|||||||
|
|
||||||
expect<KeyPaths<ExampleObject>>().type.toBe<'simplevalue' | 'config.simplevalue'>()
|
expect<KeyPaths<ExampleObject>>().type.toBe<'simplevalue' | 'config.simplevalue'>()
|
||||||
expect<KeyPaths<ExampleObject, never>>().type.toBe<
|
expect<KeyPaths<ExampleObject, never>>().type.toBe<
|
||||||
'nullvalue' | 'simplevalue' | 'config.nullvalue' | 'config.simplevalue'
|
'nullvalue' | 'simplevalue' | 'optionalKey' | 'config.nullvalue' | 'config.simplevalue'
|
||||||
>()
|
>()
|
||||||
expect<KeyPaths<ExampleObject, null>>().type.toBe<'simplevalue' | 'config.simplevalue'>()
|
expect<KeyPaths<ExampleObject, null>>().type.toBe<'simplevalue' | 'optionalKey' | 'config.simplevalue'>()
|
||||||
expect<KeyPaths<ExampleObject, string>>().type.toBe<'nullvalue' | 'config.nullvalue'>()
|
expect<KeyPaths<ExampleObject, string>>().type.toBe<'nullvalue' | 'config.nullvalue'>()
|
||||||
|
|
||||||
expect<KeyPaths<ExampleObject, null, { separator: '-' }>>().type.toBe<'simplevalue' | 'config-simplevalue'>()
|
expect<KeyPaths<ExampleObject, null, { separator: '-' }>>().type.toBe<
|
||||||
|
'simplevalue' | 'optionalKey' | 'config-simplevalue'
|
||||||
|
>()
|
||||||
expect<KeyPaths<ExampleObject, null, { leavesOnly: false }>>().type.toBe<
|
expect<KeyPaths<ExampleObject, null, { leavesOnly: false }>>().type.toBe<
|
||||||
'simplevalue' | 'config' | 'config.simplevalue'
|
'simplevalue' | 'optionalKey' | 'config' | 'config.simplevalue'
|
||||||
>()
|
>()
|
||||||
|
|
||||||
expect<KeyPaths<any, string>>().type.toBe<unknown>()
|
expect<KeyPaths<any, string>>().type.toBeAssignableTo<never>()
|
||||||
expect<KeyPaths<any, never>>().type.toBe<unknown>()
|
expect<KeyPaths<any, never>>().type.toBeAssignableTo<never>()
|
||||||
|
|
||||||
expect<KeyPaths<ExampleObject, any>>().type.toBeAssignableTo<never>()
|
expect<KeyPaths<ExampleObject, any>>().type.toBeAssignableTo<never>()
|
||||||
expect<KeyPaths<ExampleObject, unknown>>().type.toBeAssignableTo<never>()
|
expect<KeyPaths<ExampleObject, unknown>>().type.toBeAssignableTo<never>()
|
||||||
expect<KeyPaths<any, any>>().type.toBeAssignableTo<never>()
|
expect<KeyPaths<any, any>>().type.toBeAssignableTo<never>()
|
||||||
|
|||||||
Reference in New Issue
Block a user