Visit Playground
I have been experimenting with creating a versatile function that can map one string to another during the compilation phase. The idea is simple - if a string is provided as input, it should return "data", and if the input is undefined, it should return null. The main challenge lies in handling optional input files.
I have almost gotten it to work using different functions, but I encountered test failures for both scenarios which are marked as error
in the code snippet below. Additionally, I have shared a TS playground for reference.
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>>();