1

I'm attempting to create a function which accepts a fixed amount of typed parameters, but depending on the first parameter sequential parameter types are different.

So far, I haven't been able to find anything about this in the Typescript documentation.

Example:

function myFunc(name: 'one' | 'two', data?: 1 | 2) {
  //
}

// Okay
myFunc('one', 1)
myFunc('two', 2)
myFunc('two')

// Should throw an error
myFunc('one', 2)
myFunc('two', 'string')

2 Answers 2

5

You probably want to overload the function signature:

function myFunc(name: 'one', data?: 1);
function myFunc(name: 'two', data?: 2);
function myFunc(name: 'one' | 'two', data?: 1 | 2) {
  //
}

// Okay
myFunc('one', 1)
myFunc('two', 2)
myFunc('two')

// Does throw an error
myFunc('one', 2)
myFunc('two', 'string')

There's probably also a way to do this with a generic function, but overloads are the most straightforward way to do what you're after. I really recommend reading the useful and accessible TypeScript handbook for insight into stuff like this.

Hope that helps; good luck!

Sign up to request clarification or add additional context in comments.

Comments

3

As jcalz mentioned in his answer you can in fact achieve this by using generics and the new conditional types feature that will be released with TypeScript 2.8.

If you are using an npm based project you can try it out locally by installing the latest nightly build like this (the -g can be left out if you want to only install it in a local project):

npm install -g typescript@next

The code would look like this:

// the parens around the conditional expression are optional
function myFunc<T1 extends 'one' | 'two', T2 extends (T1 extends 'one' ? 1 : 2)>(name: T1, data?: T2) {
  // do what you want
}

// No errors
myFunc('one', 1);
myFunc('two', 2);
myFunc('two');

// All of these cause a compile error
myFunc('one', 2);
myFunc('two', 1);
myFunc('three');
myFunc('two', 'string')
myFunc('one', 3);

// the first invocation (i.e. myFunc('one', 1)) leads to this resolved type
function myFunc<"one", 1>(name: "one", data?: 1 | undefined): void

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.