Reputation: 59
I have a function
function foo() {
return ["", 1, () => ""];
}
types are: string
, number
and (() => string)
however after I destructure those values
const [str, num, func] = foo();
compiler treats each variable as type: string | number | (() => string)
I want to pass these variables in functions, but compiler complains that types don't match and my IDE goes nuts with red text underlying. What can I do?
Upvotes: 3
Views: 1122
Reputation: 2527
Another way to achieve this is:
function foo() {
return ['', 1, () => ''] as const
}
const [str, num, func] = foo()
Main difference with as const
and without it is that:
as const
tells ts that it is immutable value, hence ts infers concrete type which in this case is tuple of 3, and as you know, tuple can have different typesas const
, ts infers it as Array
and array takes single type parameter, but in this case array is holding string, number and func values. Hence ts infers it as (string | number | () -> string)[]
Upvotes: 6
Reputation: 1403
By default, TypeScript infers the type of an array literal not as a tuple, but as an array of a union of all of the element types. So in const x = [a, b, c];
isn't inferred to have type [A, B, C]
but instead (A | B | C)[]
.
If you want TypeScript to infer a tuple type, you have to explicitly indicate that:
const x: [A, B, C] = [a, b, c]; // this typechecks
An alternative is to use the as const
syntax:
const x = [a, b, c] as const; // infers as `readonly [A, B, C]`
This isn't the only place where TypeScript infers a less-specific type than seems possible. For example, string literals by default infer as string
instead of their literal type: let x = "word"; // string
vs let x = "word" as const; // "word"
vs const x = "word"; // "word"
Upvotes: 5
Reputation: 6853
Specify the return type of the function
function foo(): [string, number, () => string] {
return ["", 1, () => ""];
}
This will strictly type the function to return an array with:
string
number
() => string
/ function that returns stringfunction foo(): [string, number, () => string] {
return [0, 1, () => ""]; // Will shows error because index 0 is number, not string
}
Upvotes: 9