Typescript allows you to specify whether your function accept "string" or "number", by allowing you to type:
const myFunction = (foo: string | number) => foohowever, it doesn't know how to deal with more complex types (e.g. interfaces).
type IncomingErrors = ApolloError | Error;
// graphQLErrors property exists in ApolloError, but not on Error
const parseError = (err: IncomingErrors, defaultMessage: string) => {
try {
if (err && err.graphQLErrors) { // this will not compile in ts because Error does not have this property
return parseGraphQLError(err);
} else {
return parseGenericError(err, defaultMessage);
}
} catch (_) {
return err;
}
};Here are a few ways to do that so far:
type IncomingErrors = ApolloError | Error;
// notice that you have to coerce the error type into an ApolloError before it lets you access .graphQLErrors
const isGraphQLError = (err: IncomingErrors): err is ApolloError => (err as ApolloError).graphQLErrors !== undefined;
const parseError = (err: IncomingErrors, defaultMessage: string) => {
try {
if (isGraphQLError(err)) { // this function coerces the error into the ApolloError type
return parseGraphQLError(err); // isGraphQLError must have an explicit return type, or else this line will complain
} else {
return parseGenericError(err, defaultMessage);
}
} catch (_) {
return err;
}
};if you don't want to abstract it into a separate class like the docs, you can inline it, but note that you have to coerce the parameters within the conditional block into the types you want, meaning you need to coerce your object twice.
type IncomingErrors = ApolloError | Error;
const parseError = (err: IncomingErrors, defaultMessage: string) => {
try {
if ((err as ApolloError).graphQLErrors !== undefined) {
return parseGraphQLError(err as ApolloError);
} else {
return parseGenericError(err, defaultMessage);
}
} catch (_) {
return err;
}
};interface IncomingErrors extends ApolloError, Error {}
const parseError = (err: IncomingErrors, defaultMessage: string) => {
try {
if (err && err.graphQLErrors) { // your original javascript flavoured prop checking!
return parseGraphQLError(err);
} else {
return parseGenericError(err, defaultMessage);
}
} catch (_) {
return err;
}
};this cropped up in trying to implement types in Error handling, where you could be receiving GraphqlErrors/ApolloErrors or generic Errors, and you want to parse them differently according to Error type.