I'm creating an error object that conatains multiple errors that return type of IErrorForm. but if I focus on a function and set the return type of IErrorFunc, an error occurs in an object such as PermissionDenied and conversely, if I focus on the object and set the return type of IErrorObj, an error occurs in the function.
So if I use union type like below, the error occurs in a function. the error message is
'Type (from: string) => { sucess: boolean; code: number; message: string; }'does not have properties sucess, code, message of type '{ sucess: boolean; code: number; message: string; }'. ts(2739)
How can i declare return types of object?
type IErrorForm = {
sucess: boolean;
code: number;
message: string;
};
type IErrorsFunc = {
(...args: any[]): {
sucess: boolean;
code: number;
message: string;
};
};
interface IErrorObj {
[key: string]: { sucess: boolean; code: number; message: string };
}
export const CommonErrors: (IErrorObj | IErrorsFunc) = {
unexpectedError(from: string) {
return {
sucess: false,
code: 101,
message: `Unexpected error from ${from}`,
};
},
NotFound(object: string): IErrorForm {
return {
sucess: false,
code: 102,
message: `${object} not found`,
};
},
permissionDenied: {
sucess: false,
code: 103,
message: 'Permission denied: do not have permission.',
},
accessDenied(message: string): IErrorForm {
return {
sucess: false,
code: 104,
message: `Access denied: ${message}`,
};
},
};
CodePudding user response:
It looks like your intent is for CommonErrors
to be an object with arbitrary keys, and whose values are either IErrorForm
or IErrorsFunc
. If we call that type IErrorObj
, then it looks like:
interface IErrorObj {
[key: string]: IErrorForm | IErrorsFunc;
}
with a string
index signature to give us the arbitrary keys, and the union of IErrorForm
and IErrorsFunc
to give us the either/or behavior.
If we do that, then your code compiles with no error:
export const CommonErrors: IErrorObj = {
unexpectedError(from: string) {
return {
success: false,
code: 101,
message: `Unexpected error from ${from}`,
};
},
NotFound(object: string): IErrorForm {
return {
success: false,
code: 102,
message: `${object} not found`,
};
},
permissionDenied: {
success: false,
code: 103,
message: 'Permission denied: do not have permission.',
},
accessDenied(message: string): IErrorForm {
return {
success: false,
code: 104,
message: `Access denied: ${message}`,
};
},
};
It's also noteworthy that the return type of IErrorsFunc
has the same shape as IErrorForm
, which means that we can just reuse that type name due to structural typing. So your final set of types can look like:
interface IErrorForm {
success: boolean;
code: number;
message: string;
}
interface IErrorsFunc {
(...args: any[]): IErrorForm
}
interface IErrorObj {
[key: string]: IErrorForm | IErrorsFunc;
}