@types/xxxx package and had problems.Definitions by: in index.d.ts) so they can respond.How should I resolve issue with providing correct predicate type
0.29.3 and @types/yup to 0.29.7 code: Yup.string()
.required('Code is required.')
.test('duplicate-record', 'Code must be unique.', function (this: Yup.TestContext, code: string) {
for (const [i, r] of allocationTable.records.entries()) {
if (code === r.code && `records[${i}].code` !== this.path) {
return false;
}
}
return true;
}),
In this above example it looks if the code that user entered already exists in records entry and returns true if its unique else false if it already exists.
Here I'm checking if code is unique or not and returning boolean and I'm not checking if the code is string which apparently resolves the issue and I'm not sure if this is the right usage.
Type error that I get for above function is:
Argument of type '(this: TestContext<object>, code: string) => boolean' is not assignable to parameter of type 'AssertingTestFunction<any, object>'.
Signature '(this: TestContext<object>, code: string): boolean' must be a type predicate.ts(2345)
AssertingTestFunction declaration looks like below in Yup Typings:
export type AssertingTestFunction<T, C> = (this: TestContext<C>, value: any) => value is T;
Another example code is:
customerKey: Yup.object<CustomerKey>()
.nullable(true)
.shape({
customerId: Yup.number(),
customerCode: Yup.string().test('customerCodeTest', 'Customer is required', (value) => {
return (
formProps.eventType === TypeA ||
(formProps.eventType === TypeB && value) // <------ Only required if eventType B is picked
);
}),
}),
For this code test I'm checking and returning value (truthy or falsy) only if TypeB is picked else returning true. Again I'm not checking if the value is string rather existence of the value itself for a certain eventType (separate field) selection.
Here's typing error for above code:
Argument of type '(this: TestContext<object>, value: string | null | undefined) => string | boolean | null | undefined' is not assignable to parameter of type 'AssertingTestFunction<any, object>'.
Signature '(this: TestContext<object>, value: string | null | undefined): string | boolean | null | undefined' must be a type predicate.ts(2345)
For first issue, you're assigning code: string which is incorrect, just leave it as "code" (remember in tests, all properties can also be null | undefined.
function (this: Yup.TestContext, code) // Typescript will type code as string | null | undefined
For second issue, you need to use Boolean(value) or !!value or else the function will return string | boolean | null | undefined which is not the expected return value
return (
formProps.eventType === TypeA ||
(formProps.eventType === TypeB && !!value) // <------ Only required if eventType B is picked
);
@ejose19 Thank you for quick response, this resolves my issue. It seems that you have to force a boolean return value instead of relying on truthy/falsy value (which was prior allowed). Closing this issue.
hi @ejose19, sorry for bumping this. I stumbled on the same issue. I followed the actual documentation here: https://github.com/jquense/yup#mixedtestname-string-message-string--function-test-function-schema.
let jimmySchema = string().test(
'is-jimmy',
'${path} is not Jimmy',
(value, context) => value === 'jimmy',
);
Not sure where I do it wrong, but I can't get away from the TypeErrors despite using your solution above. Could you guide me through it from this Sandbox link? https://codesandbox.io/s/peaceful-colden-p29u6?file=/src/index.ts. Thanks!
@Imballinst That context as second argument is new but typescript definitions aren't updated yet. So you should use
function (value) { } instead and refer to context using this (or if you don't need the context, just use the arrow function but don't mention 2nd argument).
Got it, @ejose19. Thank you for your explanation!
Most helpful comment
@Imballinst That context as second argument is new but typescript definitions aren't updated yet. So you should use
function (value) { }instead and refer tocontextusingthis(or if you don't need thecontext, just use the arrow function but don't mention 2nd argument).