From 4cd7fcb545a94558107c7d21e0b04baf2d07ca0c Mon Sep 17 00:00:00 2001 From: Batuhan Wilhelm Date: Tue, 20 Apr 2021 05:30:33 +0300 Subject: [PATCH] [Fix] Array types generated array methods (#10) * Fix a bug where arrays types generate array methods as type * Bump version to 0.1.3 --- .gitignore | 2 ++ package-lock.json | 2 +- package.json | 2 +- spec/__type-snapshots__/types.spec.ts.snap.json | 2 +- spec/types.spec.ts | 10 +++++++++- src/types.ts | 10 +++++----- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 135aaa2..ce7d8d5 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,8 @@ .idea/**/gradle.xml .idea/**/libraries +.idea + # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using diff --git a/package-lock.json b/package-lock.json index 3cea269..992a932 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@batuhanw/haf", - "version": "0.1.2", + "version": "0.1.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 37f449b..b12f327 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@batuhanw/haf", - "version": "0.1.2", + "version": "0.1.3", "engines": { "node": ">=10" }, diff --git a/spec/__type-snapshots__/types.spec.ts.snap.json b/spec/__type-snapshots__/types.spec.ts.snap.json index bb842b3..4fe36a6 100644 --- a/spec/__type-snapshots__/types.spec.ts.snap.json +++ b/spec/__type-snapshots__/types.spec.ts.snap.json @@ -1 +1 @@ -{"getName":"string","getAge":"number","getAppearance":"Appearance","getBirthMarks":"string[]","getEyeColor":"string","getHairColor":"HairColor","getOtherColors":"string[]","getPrimary":"string","getSecondary":"string | undefined","getNoseColor":"string | undefined","getFavoriteToys":"string[]","getHasPuppies":"boolean","getLuckNumbers":"number[]","getSterilizedAt":"string | undefined","getVaccines":"Vaccine[]","getVaccines[0]":"Vaccine","getError":"string | number | boolean | string[] | (() => string) | (() => string) | (() => string | undefined) | ((...items: string[]) => number) | { (...items: ConcatArray[]): string[]; (...items: (string | ConcatArray)[]): string[]; } | ((separator?: string | undefined) => string) | (() => string[]) | (() => string | undefined) | ((start?: number | undefined, end?: number | undefined) => string[]) | ((compareFn?: ((a: string, b: string) => number) | undefined) => string[]) | { (start: number, deleteCount?: number | undefined): string[]; (start: number, deleteCount: number, ...items: string[]): string[]; } | ((...items: string[]) => number) | ((searchElement: string, fromIndex?: number | undefined) => number) | ((searchElement: string, fromIndex?: number | undefined) => number) | { (predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): boolean; } | ((predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any) => boolean) | ((callbackfn: (value: string, index: number, array: string[]) => void, thisArg?: any) => void) | ((callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | { (predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): S[]; (predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): string[]; } | { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } | { (predicate: (this: void, value: string, index: number, obj: string[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: string, index: number, obj: string[]) => unknown, thisArg?: any): string | undefined; } | ((predicate: (value: string, index: number, obj: string[]) => unknown, thisArg?: any) => number) | ((value: string, start?: number | undefined, end?: number | undefined) => string[]) | ((target: number, start: number, end?: number | undefined) => string[]) | (() => IterableIterator<[number, string]>) | (() => IterableIterator) | (() => IterableIterator) | ((searchElement: string, fromIndex?: number | undefined) => boolean) | number[] | (() => string) | (() => string) | (() => number | undefined) | ((...items: number[]) => number) | { (...items: ConcatArray[]): number[]; (...items: (number | ConcatArray)[]): number[]; } | ((separator?: string | undefined) => string) | (() => number[]) | (() => number | undefined) | ((start?: number | undefined, end?: number | undefined) => number[]) | ((compareFn?: ((a: number, b: number) => number) | undefined) => number[]) | { (start: number, deleteCount?: number | undefined): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; } | ((...items: number[]) => number) | ((searchElement: number, fromIndex?: number | undefined) => number) | ((searchElement: number, fromIndex?: number | undefined) => number) | { (predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; } | ((predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean) | ((callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void) | ((callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]) | { (predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; } | { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } | { (predicate: (this: void, value: number, index: number, obj: number[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number | undefined; } | ((predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number) | ((value: number, start?: number | undefined, end?: number | undefined) => number[]) | ((target: number, start: number, end?: number | undefined) => number[]) | (() => IterableIterator<[number, number]>) | (() => IterableIterator) | (() => IterableIterator) | ((searchElement: number, fromIndex?: number | undefined) => boolean) | Vaccine[] | (() => string) | (() => string) | (() => Vaccine | undefined) | ((...items: Vaccine[]) => number) | { (...items: ConcatArray[]): Vaccine[]; (...items: (Vaccine | ConcatArray)[]): Vaccine[]; } | ((separator?: string | undefined) => string) | (() => Vaccine[]) | (() => Vaccine | undefined) | ((start?: number | undefined, end?: number | undefined) => Vaccine[]) | ((compareFn?: ((a: Vaccine, b: Vaccine) => number) | undefined) => Vaccine[]) | { (start: number, deleteCount?: number | undefined): Vaccine[]; (start: number, deleteCount: number, ...items: Vaccine[]): Vaccine[]; } | ((...items: Vaccine[]) => number) | ((searchElement: Vaccine, fromIndex?: number | undefined) => number) | ((searchElement: Vaccine, fromIndex?: number | undefined) => number) | { (predicate: (value: Vaccine, index: number, array: Vaccine[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: Vaccine, index: number, array: Vaccine[]) => unknown, thisArg?: any): boolean; } | ((predicate: (value: Vaccine, index: number, array: Vaccine[]) => unknown, thisArg?: any) => boolean) | ((callbackfn: (value: Vaccine, index: number, array: Vaccine[]) => void, thisArg?: any) => void) | ((callbackfn: (value: Vaccine, index: number, array: Vaccine[]) => U, thisArg?: any) => U[]) | { (predicate: (value: Vaccine, index: number, array: Vaccine[]) => value is S, thisArg?: any): S[]; (predicate: (value: Vaccine, index: number, array: Vaccine[]) => unknown, thisArg?: any): Vaccine[]; } | { (callbackfn: (previousValue: Vaccine, currentValue: Vaccine, currentIndex: number, array: Vaccine[]) => Vaccine): Vaccine; (callbackfn: (previousValue: Vaccine, currentValue: Vaccine, currentIndex: number, array: Vaccine[]) => Vaccine, initialValue: Vaccine): Vaccine; (callbackfn: (previousValue: U, currentValue: Vaccine, currentIndex: number, array: Vaccine[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: Vaccine, currentValue: Vaccine, currentIndex: number, array: Vaccine[]) => Vaccine): Vaccine; (callbackfn: (previousValue: Vaccine, currentValue: Vaccine, currentIndex: number, array: Vaccine[]) => Vaccine, initialValue: Vaccine): Vaccine; (callbackfn: (previousValue: U, currentValue: Vaccine, currentIndex: number, array: Vaccine[]) => U, initialValue: U): U; } | { (predicate: (this: void, value: Vaccine, index: number, obj: Vaccine[]) => value is S, thisArg?: any): S | undefined; (predicate: (value: Vaccine, index: number, obj: Vaccine[]) => unknown, thisArg?: any): Vaccine | undefined; } | ((predicate: (value: Vaccine, index: number, obj: Vaccine[]) => unknown, thisArg?: any) => number) | ((value: Vaccine, start?: number | undefined, end?: number | undefined) => Vaccine[]) | ((target: number, start: number, end?: number | undefined) => Vaccine[]) | (() => IterableIterator<[number, Vaccine]>) | (() => IterableIterator) | (() => IterableIterator) | ((searchElement: Vaccine, fromIndex?: number | undefined) => boolean) | Appearance | HairColor | undefined"} +{"getName":"string","getAge":"number","getAppearance":"Appearance","getBirthMarks":"string[]","getEyeColor":"string","getHairColor":"HairColor","getOtherColors":"string[]","getPrimary":"string","getSecondary":"string | undefined","getNoseColor":"string | undefined","getFavoriteToys":"string[]","getHasPuppies":"boolean","getLuckyNumbers":"number[]","getSterilizedAt":"string | undefined","getVaccines":"Vaccine[]","getVaccines[0]":"Vaccine","getError":"string | number | boolean | string[] | number[] | Vaccine[] | Appearance | HairColor | undefined","getArrayError":"string | number | boolean | string[] | number[] | Vaccine[] | Appearance | HairColor | undefined","getNestedArrayError":"string | number | boolean | string[] | number[] | Vaccine[] | Appearance | HairColor | undefined"} diff --git a/spec/types.spec.ts b/spec/types.spec.ts index 50f6fc6..7854dcf 100644 --- a/spec/types.spec.ts +++ b/spec/types.spec.ts @@ -63,7 +63,7 @@ describe('Type tests', () => { // $ExpectTypeSnapshot getHasPuppies haf.get('hasPuppies'); - // $ExpectTypeSnapshot getLuckNumbers + // $ExpectTypeSnapshot getLuckyNumbers haf.get('luckyNumbers'); // $ExpectTypeSnapshot getSterilizedAt @@ -78,5 +78,13 @@ describe('Type tests', () => { // @ts-expect-error: Getting a key that doesn't exist // $ExpectTypeSnapshot getError haf.get('non-existent'); + + // @ts-expect-error: Arrays shouldn't generate types of array methods + // $ExpectTypeSnapshot getArrayError + haf.get('luckyNumbers.concat'); + + // @ts-expect-error: Deeply nested arrays shouldn't generate types of array methods + // $ExpectTypeSnapshot getNestedArrayError + haf.get('appearance.hairColor.otherColors.concat'); }); }); diff --git a/src/types.ts b/src/types.ts index 8677e55..e2ae24b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -25,11 +25,11 @@ export type FlattenedWithDotNotation = /* then, for each sub-object, recurse */ IntersectValuesOf< { - [K in string & keyof Schema as AddPrefix]: Schema[K] extends Record< - string, - // eslint-disable-next-line - any - > + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [K in string & keyof Schema as AddPrefix]: Schema[K] extends Array + ? never + // eslint-disable-next-line @typescript-eslint/ban-types + : Schema[K] extends object ? FlattenedWithDotNotation> : never; }