Issue
I'm trying to do the following
If actions property exist, and callbacks within the actions properties that return string, then return X or Y.
Above code expressed:
// type MappedType<T> = {
// [K in keyof T]: T[K] extends () => string ? T[K] : never
// }
// it should check if object has property of actions, also check if properties within actions are callbacks that return string
type HasStringReturn<Options> = Options extends { actions: { [K in keyof Options]: Options[K] extends () => string ? Options[K] : never } } ? Options: 'Something went wrong';
type StringCallback = {
actions: {
test: () => 'i love owls i really do.'
}
}
type FinalCheck = HasStringReturn<StringCallback>
Currently, it returns "Something went wrong" even though the type is correct. Maybe im missing something.
I'm just trying to check for an existence of actions, and within actions check if the properties are callbacks that return a string. That's pretty much it.
Is this where i have to use infer
or just a generic conditional would be suffice. Curious to know. Thanks.
Solution
The problem with your version is that you are checking Options
, not Options["actions"]
for the function properties. You'll need to push your analysis down one level, possibly by using conditional type inference to give a type parameter name to Options["actions"]
, as shown here:
type HasStringReturn<T> =
T extends { actions: infer A } ?
A extends { [K in keyof A]: A[K] extends () => string ? A[K] : never } ? T :
"something went wrong" :
"something continued to go wrong";
(Note I've changed Options
to T
to be more in line with type parameter naming conventions, but you can do it however you want). Notice that this is a pair of checks, each one of which can fail and result in the error condition. First we check if T
has an actions
property, and then we check if that actions
property is of the right type.
Let's make sure it behaves as expected:
type StringCallback = {
actions: {
test: () => 'i love owls i really do.',
}
}
type Good = HasStringReturn<StringCallback>
/* type Good = {
actions: {
test: () => 'i love owls i really do.';
};
} */
type BadStringCallback = {
actions: {
test: () => 'i love owls i really do.',
oops: number
}
}
type Bad = HasStringReturn<BadStringCallback>;
// type Bad = "something went wrong"
type ReallyBadStringCallback = { test(): string }
type ReallyBad = HasStringReturn<ReallyBadStringCallback>;
// type ReallyBad = "something continued to go wrong"
Looks good!
Answered By - jcalz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.