0

Link to TS Playground

I am trying to create a generic function that can essentially map one string to another at compile time. If any string is inputted, then " data" should be returned, if undefined, then null should be returned. The problem is based on making `input file optional.

I have it almost working w/with different functions, but I have test cases that fail for both that I have marked with error below. I also have a TS playground setup.

type OutputType<T> = T extends string ? "data" : null;

function map<T extends string | undefined, V extends OutputType<T>>(
  inputFile: T
): V {
  return (inputFile ? "data" : null) as V;
}

function mapOptional<
  T extends string | undefined = undefined,
  V extends OutputType<T> = OutputType<T>
>(inputFile?: T): V {
  return (inputFile ? "data" : null) as V;
}

const map1 = map("file2");
assertTrue<TypeEqual<"data", typeof map1>>();
const map2 = map("x" as string | undefined);
assertTrue<TypeEqual<"data" | null, typeof map2>>();
const map3 = map(undefined);
assertTrue<TypeEqual<null, typeof map3>>();
const map4 = map(); // error
assertTrue<TypeEqual<null, typeof map4>>(); // error

const mapOptional1 = mapOptional("file2");
assertTrue<TypeEqual<"data", typeof mapOptional1>>();
const mapOptional2 = mapOptional("x" as string | undefined);
assertTrue<TypeEqual<"data" | null, typeof mapOptional2>>(); // error
const mapOptional3 = mapOptional(undefined);
assertTrue<TypeEqual<null, typeof mapOptional3>>();
const mapOptional4 = mapOptional();
assertTrue<TypeEqual<null, typeof mapOptional4>>();
2
  • Please mark where you have expected errors Commented May 23, 2021 at 17:48
  • I already marked them with error Commented May 23, 2021 at 17:55

1 Answer 1

1

It's a tricky one, because the optionality of the parameter is not explicitly part of its generic type.

I managed to work around that by just using multiple function declarations:

function mapOptional(): null;
function mapOptional(inputFile: undefined): null;
function mapOptional<T extends string>(inputFile: T): 'data';
function mapOptional<T extends string | undefined>(inputFile: T): 'data' | null;
function mapOptional<
  T extends string | undefined
>(inputFile?: T): 'data' | null {
  return (inputFile ? "data" : null) as any;
}
Sign up to request clarification or add additional context in comments.

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.