mitchkman
mitchkman

Reputation: 6680

TypeScript: "Overload signatures must all be ambient or non-ambient" when overloading a function

I am trying to create an overloaded function getDefaultPath so that it can only accept certain type combinations.

I tried using function signature declarations but it results in a confusing error message for both function declarations:

Overload signatures must all be ambient or non-ambient.

// type declartions
export enum TABS {
  TAB_A,
  TAB_B
}

export interface TabAParams {
   ...
}

export interface TabBParams {
   ...
}

// Overload signatures
export declare function getDefaultPath(tab: TABS.TAB_A, pathParams: TabAParams): string;
export declare function getDefaultPath(tab: TABS.TAB_B, pathParams: TabBParams): string;

// this function is to be overloaded
export function getDefaultPath(
  tab,
  pathParams
) {
  switch (tab) {
    case TABS.TAB_A:
      return getTabAPath(pathParams); // only accepts TabAParams
    case TABS.TAB_B:
      return getTabBPath(pathParams); // only accepts TabBParams
    default:
      throw new UnreachableCaseError(tab);
  }
}

// helps to avoid missing cases
export default class UnreachableCaseError extends Error {
  constructor(val: never) {
    super(`Unreachable case: ${val}`);
  }
}

Upvotes: 0

Views: 2452

Answers (2)

Richard Palethorpe
Richard Palethorpe

Reputation: 81

There is another way without explicitly using overloading. The arguments to a function in js/ts are just an array. TS allows you to specify the types of individual elements in an array. So the following is possible:

type GetDefaultPathParams = (
  [TABS.TAB_A, TabAParams] |
  [TABS.TAB_B, TabBParams]
);

export function getDefaultPath(...params: GetDefaultPathParams)
{
  const tab = params[0];
  const pathParams = params[1];

  switch (tab) {
    case TABS.TAB_A:
      return getTabAPath(pathParams); // only accepts TabAParams
    case TABS.TAB_B:
      return getTabBPath(pathParams); // only accepts TabBParams
    default:
      throw new UnreachableCaseError(tab);
  }
}

Upvotes: 1

Andrei
Andrei

Reputation: 12196

just remove the declare word from overloads and the error is gone.

also take into account that the actual implementation is not checked for types properly and couldn't be changed to be checked, in a way you are trying to implement it, considering what TS have at the moment. Just the usage of this function will be checked properly

Upvotes: 1

Related Questions