Home > front end >  typescript: how to declare function rturn type that inside of object
typescript: how to declare function rturn type that inside of object

Time:02-01

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;
}

Playground link to code

  •  Tags:  
  • Related