#Getting type inference for a simple object in a conditional

9 messages · Page 1 of 1 (latest)

mystic atlas
#
class Foo {
    constructor(public contained : number) {}
}

type FooStruct = {contained: number};

function meth(x: Foo) {
    return x.contained *= x.contained;
}

function match(arg: unknown) {
    if (arg 
    && typeof arg === "object" 
    && 'contained' in arg // This line should be unnecessary anyways
    && typeof arg.contained === "number") {
        meth(arg); // TS incorrectly flags this as an error
        // Inferred type: arg: object & Record<'contained', unknown>
    }

    if (arg instanceof Foo) {
        meth(arg); // OK
    }
}

How to get TS to correctly infer the type for the first meth() invocation?

Playground link below

rough patrolBOT
mystic atlas
#

Should ideally also work if the && 'contained' in arg check is omitted

nova moat
#

TS doesn't like to narrow objects based on properties

rough patrolBOT
#
sandiford#0

Preview:```ts
class Foo {
constructor(public contained: number) {}
}

type FooStruct = {contained: number}

function meth(x: Foo) {
return (x.contained *= x.contained)
}

function IsFoo(u: unknown): u is Foo {
return (
typeof u === "object" &&
...```

nova moat
#

You can assert it

#

It will narrow in properties if you have a union of types to choose between, but I don't think it will make a whole new object typing for you based on a property check

haughty tusk
#

besides factoring out a type guard function like Bert suggested, you could also construct a new object to use as the argument: