Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typescript interface conditional optional parameters

Tags:

typescript

Can we achieve this :

interface IMyInterface{
    firstname:string  // this means firstname is mandatory

    name:string  // this also means name is mandatory
}

How can I say, either one of firstname or name is optional (?), depending on if the other one is provided ?

Or if that's not possible, what are the other options ?

EDIT : This is not a duplicate of Typescript Interface - Possible to make "one or the other" properties required?.

We don't want to create a separate interface for every single optional element simply because the maintenance and naming and the refactoring will be a pain in the neck and it's not reusable.

like image 652
Milad Avatar asked Mar 28 '18 00:03

Milad


People also ask

How do you pass optional parameters in TypeScript?

In Typescript, making optional parameters is done by appending the “?” at the end of the parameter name in the function when declaring the parameters and the parameters which are not marked with “?” i.e not optional parameter are called as default parameters or normal parameters where it is must and compulsory to pass ...

Does TypeScript have optional parameters?

TypeScript provides a Optional parameters feature. By using Optional parameters featuers, we can declare some paramters in the function optional, so that client need not required to pass value to optional parameters.

How do you make a function parameter optional in TypeScript?

In Typescript, “?” represents optional parameters. We use optional parameters when it's not mandatory for that parameter to have a value or to be specified. Even if a function specifies parameters, you can call it without giving any arguments in JavaScript.

Does TypeScript have optionals?

You must tell TypeScript if a property is optional. First, if you don't tell TypeScript that a property is optional, it will expect it to be set. Adding ? to the property name on a type, interface, or class definition will mark that property as optional.


1 Answers

Here is a generic way of saying "OneOf" these keys, you might be able to use it here:

type EachOfTmp<T> = {// to make OneOf less gross
  [K in Keys<T>]: {
    _: {[X in K]: T[K]};
  }
};

// require only one of the keys
export type OneOf<T> = EachOfTmp<T>[Keys<T>]["_"] & Partial<T>;

const thing1: OneOf<{ a: number; b: number }> = { a: 2 } // valid
const thing2: OneOf<{ a: number; b: number }> = { b: 2 } // valid
const thing3: OneOf<{ a: number; b: number }> = {} // invalid

EDIT: oops, I forgot I use this convenience Keys deal -

export type Keys<T> = keyof T;
export function Keys<T>(o: T) {
  if (!o) {
    return [];
  }
  return Object.keys(o) as Keys<T>[];
}
like image 200
Catalyst Avatar answered Sep 19 '22 20:09

Catalyst