-
Notifications
You must be signed in to change notification settings - Fork 901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add types to ErrorFactory message parameters #1720
Conversation
fe286a6
to
759c4c8
Compare
759c4c8
to
d71ef8c
Compare
You can use rest parameter with tuple type to conditionally require the second parameter. But it still doesn't work in this case, because export class ErrorFactory<
ErrorCode extends string,
ErrorParams extends Partial<{ readonly [K in ErrorCode]: ErrorData }> = {}
> {
create<K extends ErrorCode>(
code: K,
...data: ErrorParams[K] extends undefined ? [] : [ErrorParams[K]]
): FirebaseError {
}
} To make interface AppErrorParams {
[AppErrorCode.SOME_ERROR]: undefined,
[AppErrorCode.WITH_PARAMS]: { param: string; optParam?: string };
// See https://github.com/Microsoft/TypeScript/issues/8032
[AppErrorCode.WITHOUT_PARAMS]: undefined;
} Then it works as expected in all cases. ERROR_FACTORY.create(ErrorCode.SOME_ERROR); // good
ERROR_FACTORY.create(ErrorCode.SOME_ERROR, {}); // error
ERROR_FACTORY.create(ErrorCode.SOME_ERROR, { param: 'param' }); // error
ERROR_FACTORY.create(ErrorCode.WITH_PARAMS); // error
ERROR_FACTORY.create(ErrorCode.WITH_PARAMS, { param: 'param' }); // good
ERROR_FACTORY.create(ErrorCode.WITH_PARAMS, {
param: 'param',
optParam: 'optParam'
}); // good
ERROR_FACTORY.create(ErrorCode.WITHOUT_PARAMS); // good
ERROR_FACTORY.create(ErrorCode.WITHOUT_PARAMS, {}); // error
ERROR_FACTORY.create(ErrorCode.WITH_PARAMS, {}); // error
ERROR_FACTORY.create(ErrorCode.WITH_PARAMS, {
param: 'param',
otherParam: 'otherParam'
}); // error
// This one doesn't have any params.
ERROR_FACTORY.create(ErrorCode.WITHOUT_PARAMS, { param: 'whatever' }); The solution is not ideal as we need to define fields without parameters as undefined, but it's 100% type safe. Let me know if you find better solutions... I guess |
12e5a82
to
80c39fe
Compare
d71ef8c
to
1ddf849
Compare
Thanks for taking a look! Yeah, my first version of this was using a rest parameter as well, but it looks pretty bad in VSCode IntelliSense: For the In the end, I changed it to Changing to the rest parameter also makes this stricter, meaning if there's no entry in the interface for that One last question is whether we should allow omitting I updated the example in my original post. |
1ddf849
to
e0b87ae
Compare
e0b87ae
to
8687500
Compare
8ff851c
to
e9e4ef0
Compare
8687500
to
4a518e7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This makes it possible to have static type checking for error parameters.
Example: