1

I have the following code that is currently working:

type ParamType = { a: string, b: string } | { c: string }

if ('a' in params) {
  doSomethingA(params)
} else {
  doSomethingC(params)
}

doSomethingA only accepts { a: string, b: string } while doSomethingC only accepts { c: string }

The issue I'm running into is I recently changed a key in { a: string, b: string } and typescript didn't complain on the 'a' in params as I would have liked. So I made the following update:

type A = { a: string, d: string }
type B = { c: string }
type ParamType = A | B

const testKey: keyof A = 'd'

if (testKey in params) {
  doSomethingA(params)
} else {
  doSomethingC(params)
}

however now typescript does not infer the type of params correctly within the if/else and I get:

Property 'd' is missing in type 'B' but required in type 'A'.

Is there a way to ensure that the key I'm using in my if statement is one of the keys from A while also getting correct types within the if statement itself?
0

I think TypeScript doesn't have that functionality (yet?). As you seen if ('d' in params) { works to narrow down the types in if branches, but even const testKey = 'd'; if (testKey in params) { doesn't work despite the fact that testKey is precisely the same type as 'd'365体育足球滚球比分 in that case.

365体育足球滚球比分You can create custom type guard function that checks the keys but you will have to implement it and repeat in the implementation the keys you defined for type because types don't follow into runtime code

type A = { a: string, d: string }
type B = { c: string }
type ParamType = A | B

function isA(ob:A|B, key:keyof A | keyof B): ob is A {
    return new Set(['a', 'd']).has(key);
}

const g = (params:ParamType) =>  {
    const testKey:keyof A = 'a'

    if (isA(params, testKey)) {
        doSomethingD(params)
    } else {
        doSomethingC(params)
    }
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.