Reputation: 758
So I have this function that splits a string based on the provided separator and will convert the values of the array to either a string or number based on the convertTo
value.
If I call this function with convertTo = 'number'
, typescript still assumes the result is of type Array<string | number>
, but ideally I would like it to be of type Array<number>
.
What would be the way to achieve this in Typescript?
type Options = {
separator?: string;
convertTo?: 'string' | 'number';
};
export function splitAndTrim(value: string, options: Options = {}): Array<string | number> {
const { separator = ',', convertTo = 'string' } = options;
return value.split(separator).map(entry => {
if (convertTo === 'string') {
return entry.trim();
}
return Number(entry);
});
}
// parsedValue is still of type Array<string | number>.
// Is there a way of having it of type Array<number>? I was hoping TS could infer that.
const parsedValue = splitAndTrim(value, {convertTo: 'number'});
Note the function works as I expect, the question is regarding typescript typings.
Any help is appreciated!
Upvotes: 1
Views: 1645
Reputation: 68
Your function can return either array of strings or array of numbers, so the return type of the function will always be Array. But you always can check the type of parsedValue with "typeof" operator
Edit: Try function overloading
You can have multiple functions with the same name but different parameter types and return type
Your code should look something like this:
export function splitAndTrim(value: string, returnNum: true, separator?: string): Array<number>;
export function splitAndTrim(value: string, returnNum: false, separator?: string): Array<string>;
export function splitAndTrim(value: string, returnNum: boolean, separator: string = ','): any {
return value.split(separator).map(entry => {
if (returnNum) {
return Number(entry);
}
return entry.trim();
});
}
const a = splitAndTrim('1', true); // number[] type
const b = splitAndTrim('1', false); // string[] type
Upvotes: 2