I'm sorry for the vague title, but my question here comes from not really understanding what TS is doing in this situation so I wasn't sure what to call it. Basically, the question is--why does this code fail:
type Broken<T extends string | number> = T extends string ? T : null
let foo:Broken<string>
let value: string
foo = value
let value2: string | number
// this error makes sense to me: value2 could be a number
foo = value2
if(typeof value2 === "string")
{
// and it makes sense to me this works, because now we know they are both strings
foo = value2
}
function testBroken<T extends string | number>(value: T ){
let bar: Broken<T>
// i guess i expect this error, but i'm not sure i understand why TS says the error
// is that "string" is not assignable to Broken<T>
bar = value
if(typeof value === "string"){
// Why is this an error? if "bar" is narrowed to string don't we know that Broken<T>
// is also "string"?
bar = value
}
}
Playground here
More specifically, why do the assignments to bar
generate errors (especially the second one) but not the second assignment to foo
. I think it has something to do with type distribution in conditional types, but I can't really wrap my head around it.
Can someone explain what is going on here? (Note: This question is more about understanding what TS is doing here, rather than coming up with a workaround for the typing).