#Can't get compiler to narrow type of variable in function body

1 messages · Page 1 of 1 (latest)

tulip peak
#
type Conditional<T extends boolean> = T extends true ? string : null
type CaseTrue = Conditional<true>
type CaseFalse = Conditional<false>

const str: CaseTrue = 'this works .-.'
const nll: CaseFalse = null

function isTrue(value: boolean): value is true {
    return value === true
}

function test<T extends boolean>(bool: T): T extends true ? string : null {
    if (isTrue(bool)) {
        let b = bool // b is T & boolean
        return 'should have worked, no?'
        // this return errors with: Type '"should have worked, no?"' is not assignable to type 'T extends true ? string : null'. (2322)
    } else {
        return null // this return errors with: Type null is not assignable to type 'T extends true ? string : null'. (2322)
    }
}

function test2<T extends boolean>(bool: T): T extends true ? string : null {
    if (bool === true) {
        let b = bool
        return 'should have worked, no?'
        // this return errors with: Type '"should have worked, no?"' is not assignable to type 'T extends true ? string : null'. (2322)
    } else {
        return null // this return errors with: Type null is not assignable to type 'T extends true ? string : null'. (2322)
    }
}
minor radishBOT
#
Gabriel Porto#2177

Preview:```ts
type Conditional<T extends boolean> = T extends true
? string
: null
type CaseTrue = Conditional<true>
type CaseFalse = Conditional<false>

const str: CaseTrue = "this works .-."
const nll: CaseFalse = null

function isTrue(value: boolean): value is true
...```

tulip peak
#

I'm expecting that by calling test(true) the return type is string and test(false) the return type is null, this is already the case but the function body itself seems to be
unable to narrow the return type to string or null based on bool's type.

pastel sedge
#

T could be boolean

tulip peak
#

right, but what about the return type then?

pastel sedge
#

you could use overloads

tulip peak
#

yeah thats what I ultimately ended up using

#

but I was hoping that it was possible to do it without overloads