diff --git a/test/anyPass.test.ts b/test/anyPass.test.ts index ff46aa5..b3f9631 100644 --- a/test/anyPass.test.ts +++ b/test/anyPass.test.ts @@ -25,7 +25,7 @@ expectType<boolean>( }) ); -expectError( +expectType<boolean>( isVampire({ age: 21, garlic_allergy: true, diff --git a/test/propEq.test.ts b/test/propEq.test.ts index dc5b909..f64c812 100644 --- a/test/propEq.test.ts +++ b/test/propEq.test.ts @@ -1,6 +1,6 @@ import { expectError, expectType } from 'tsd'; -import { propEq } from '../es'; +import {__, propEq} from '../es'; type Obj = { union: 'foo' | 'bar'; @@ -12,28 +12,41 @@ type Obj = { // propEq(val, name, obj) expectType<boolean>(propEq('foo', 'union', {} as Obj)); -// non-union string fails -expectError(propEq('nope', 'union', {} as Obj)); -// completely different type fails -expectError(propEq(2, 'union', {} as Obj)); +// propEq doesn't create unnecessary values constraint for object +expectType<boolean>(propEq(1, 'union', {} as Obj)); +// unknown field names fails +expectError(propEq('foo', 'unknown', {} as Obj)); // propEq(val)(name)(obj) expectType<boolean>(propEq('foo')('union')({} as Obj)); // 'nope' is inferred as 'string' here. expectType<boolean>(propEq('nope')('union')({} as Obj)); -// completely different type fails -expectError(propEq(2)('union')({} as Obj)); +// unknown field names fails +expectError(propEq('foo')('unknown')({} as Obj)); // propEq(val)(name), obj) expectType<boolean>(propEq('foo')('union', {} as Obj)); // 'nope' is inferred as 'string' here. expectType<boolean>(propEq('nope')('union', {} as Obj)); -// completely different type fails -expectError(propEq(2)('union', {} as Obj)); +// unknown field names fails +expectError(propEq('foo')('unknown', {} as Obj)); // propEq(val, name)(obj) expectType<boolean>(propEq('foo', 'union')({} as Obj)); // 'nope' is inferred as 'string' here. expectType<boolean>(propEq('nope', 'union')({} as Obj)); -// completely different type fails -expectError(propEq(2, 'union')({} as Obj)); +// unknown field names fails +expectError(propEq('foo', 'unknown')({} as Obj)); + +// propEq(__, name, obj)(val) +expectType<boolean>(propEq(__, 'union', {} as Obj)('foo')); +// propEq(val, __, obj)(val) +expectType<boolean>(propEq('foo', __, {} as Obj)('union')); +// propEq(__, __, obj)(val, name) +expectType<boolean>(propEq(__, __, {} as Obj)('foo', 'union')); +// propEq(__, __, obj)(val)(name) +expectType<boolean>(propEq(__, __, {} as Obj)('foo')('union')); + +expectError(propEq('foo', __, {} as Obj)('unknown')); +expectError(propEq(__, __, {} as Obj)('foo', 'unknown')); +expectError(propEq(__, __, {} as Obj)('foo')('unknown')); diff --git a/types/propEq.d.ts b/types/propEq.d.ts index e667fb2..aa01126 100644 --- a/types/propEq.d.ts +++ b/types/propEq.d.ts @@ -1,6 +1,31 @@ -export function propEq<T>(val: T): { - <K extends PropertyKey>(name: K): (obj: Record<K, T>) => boolean; - <K extends PropertyKey>(name: K, obj: Record<K, T>): boolean; +import { Placeholder } from 'ramda'; + +export function propEq(__: Placeholder): never; +export function propEq<V>(val: V): { + <K extends PropertyKey>(name: K): (obj: Record<K, any>) => boolean; + <U extends Record<PropertyKey, any>>(__: Placeholder, obj: U): (name: keyof U) => boolean; + <K extends keyof U, U extends Record<PropertyKey, any>>(name: K, obj: U): boolean; }; -export function propEq<T, K extends PropertyKey>(val: T, name: K): (obj: Record<K, T>) => boolean; -export function propEq<K extends keyof U, U>(val: U[K], name: K, obj: U): boolean; +export function propEq<K extends PropertyKey>(__: Placeholder, name: K): { + (__: Placeholder, obj: Record<K, any>): <V>(val: V) => boolean; + <V>(val: V, obj: Record<K, any>): boolean + <V>(val: V): (obj: Record<K, any>) => boolean +}; +export function propEq<V, K extends PropertyKey>(val: V, name: K): (obj: Record<K, any>) => boolean; + + +export function propEq<U extends Record<any, any>>(__: Placeholder, ___: Placeholder, obj: U): { + (__: Placeholder, name: keyof U): { + (__: Placeholder): never; + <V>(val: V): boolean; + } + <V>(val: V, name: keyof U): boolean; + (__: Placeholder): never; + <V>(val: V): (name: keyof U) => boolean; +}; +export function propEq<K extends PropertyKey>(__: Placeholder, name: K, obj: Record<K, any>): { + (__: Placeholder): never; + <V>(val: V): boolean; +}; +export function propEq<V, U extends Record<any, any>>(val: V, __: Placeholder, obj: U): (name: keyof U) => boolean; +export function propEq<V, U extends Record<any, any>>(val: V, name: keyof U, obj: U): boolean;