Consider this code snippet:
type MyType = "value1" | "value2"
function myFunction(myParam: MyType) {
let myString: string
if(myParam === "value1") {
myString = "foo1"
}
else if(myParam === "value2") {
myString = "foo2"
}
myOtherFunction(myString)
}
function myOtherFunction(anotherParam: string) { ... }
Since the if/if else handles all values of myParam, there is no way myString can be unassigned. Still, TypeScript complains: Variable 'myString' is used before being assigned.
How can I get rid of that error without substantial code changes?
(Of course, I could remove the if(myParam === "value2") part, but that makes the code much less readable. A switch works as well I think. But I dislike those.)
CodePudding user response:
The way to "fix" this is to throw in an additional else
type MyType = "value1" | "value2"
function myFunction(myParam: MyType) {
let myString: string
if(myParam === "value1") {
myString = "foo1"
}
else if(myParam === "value2") {
myString = "foo2"
}
else {
// const unknownType = myParam; // You can use this line to check what type is myParam
throw new Error('myParam is wrong!');
}
// ...
}
By throwing in the else you ensure typescript that the path that should not be taken really cannot be taken.
Also for this kind of thing, I tend to use switch for clarity, but it is viable only for primitives...
CodePudding user response:
The if .. else is exhaustive only when the last else does not have if:
type MyType = "value1" | "value2"
function myFunction(myParam: MyType) {
let myString: string
if(myParam === "value1") {
myString = "foo1"
}
else { // <-- no "if" here
myString = "foo2"
}
// `myString` is definitely assigned a value here
myOtherFunction(myString)
}
function myOtherFunction(anotherParam: string) { ... }
CodePudding user response:
You could switch to switch (ugh.., sorry) and make the second case default:
type MyType = "value1" | "value2"
function myFunction(myParam: MyType) {
let myString: string
switch (myParam) {
case "value1":
myString = "foo1"
break
case "value2":
default:
myString = "foo2"
break
}
myOtherFunction(myString)
}
function myOtherFunction(anotherParam: string) { ... }
