-
Notifications
You must be signed in to change notification settings - Fork 11
Closed
Description
Hi there,
First of - thanks for this library. Its very helpful.
I am having issues testing type guards that use generics. For example, I have a guard that looks like this
const createGuard = <T>(
validator: (value: unknown) => boolean,
label: string,
) => {
return (input: unknown, throwError = false): input is T => {
if (!validator(input)) {
if (throwError) {
throw new TypeError(`expected input to be ${label}`);
}
return false;
}
return true;
};
};
export function isArray<T>(
input: unknown,
valueGuard: (value: unknown) => boolean,
throwError = false,
): input is T[] {
return createGuard<T[]>(
(value) => Array.isArray(value) && value.every(valueGuard),
'Array',
)(input, throwError);
}I then test it like so:
describe('isArray', () => {
it('returns true for positively tested array values', () => {
expect(isArray<string>(stringArray, isString)).toBeTruthy();
expect(isArray<number>(numberArray, isNumber)).toBeTruthy();
expect(isArray<symbol>(symbolArray, isSymbol)).toBeTruthy();
expect(isArray<object>(recordArray, isObject)).toBeTruthy();
expect(
isArray<string | number>(
[...stringArray, ...numberArray],
isUnion<string | number>(isString, isNumber),
),
).toBeTruthy();
});
it('returns false for negatively tested array values', () => {
expect(isArray<string>(stringArray, isNumber)).toBeFalsy();
expect(isArray<number>(numberArray, isString)).toBeFalsy();
expect(isArray<symbol>(symbolArray, isObject)).toBeFalsy();
expect(isArray<object>(recordArray, isSymbol)).toBeFalsy();
expect(
isArray<string | number>(
[...symbolArray, ...recordArray],
isUnion<string | number>(isString, isNumber),
),
).toBeFalsy();
});
it('returns false for non-array values', () => {
expect(isArray<string>('', isString)).toBeFalsy();
expect(isArray<string>(null, isString)).toBeFalsy();
expect(isArray<string>(123, isString)).toBeFalsy();
expect(isArray<string>(Symbol(), isString)).toBeFalsy();
expect(isArray<string>({}, isString)).toBeFalsy();
});
it('throws error when throwError = true', () => {
expect(() => isArray<string>('', isString, true)).toThrow();
expect(() => isArray<string>(null, isString, true)).toThrow();
expect(() => isArray<string>(123, isString, true)).toThrow();
});
it('guards type correctly', () => {
const unknownArray: unknown = [...stringArray];
if (isArray<string>(unknownArray, isString)) {
expectTypeOf(unknownArray).toMatchTypeOf(stringArray);
}
});
});Note the last it() where I use the expect-type library. This is the only way i figured that actually works for testing generics with this library. Is there another solution or maybe a planned fix?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels