Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to resolve "Type is not assignable to type" in TypeScript if statement?

I have 2 sets of keys: KEY_SET_1 and KEY_SET_2. KEY_SET_1 has keys A to D while KEY_SET_2 has keys E to H. I have a function that needs to handle key in both key sets differently. However, I run into an error that says

Argument of type ‘AllKeySetType’ is not assignable to parameter of type ‘"A" | "B" | "C" | "D"’. Type ‘"E"’ is not assignable to type ‘"A" | "B" | "C" | "D"’.".

I wonder what is the best way to go about it in TypeScript in this case? Thanks.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

TypeScript Playground: https://www.typescriptlang.org/play?#code/MYewdgzgLgBA0gUQJoH0DKCAqKCMMC8MA2gOQCCJANDCQEJU0DCDJAIiQLowCGEMokKAG4AUAOjxk6LCgBMBYiQQsAYiwDiLABKcefccJEioATwAOAU3gWTaC1ByZzVwgApTlkADNJqDNhwASiIwAFcAWwAjCwAnDlEPKzgbOyhZJ0sFd2dvX2lsWWCwqNj442cYMgAbKuTbewyXa3qHRpgAH2bU9OdRMXAJAAtuMAATKos6rIBrGwAuSpq61MbAggA+GABvERgYAEsfV0Q-GRwAOn2wYCrQ0YsIV1mTQMCdvb2Aek+YLRHxqzPGAQewwHC7GAAXwsVRB7w+31+-wmMCBINgsghkJEkKAA

const KEY_SET_1 = ['A', 'B', 'C', 'D'] as const;
const KEY_SET_2 = ['E', 'F', 'G', 'H'] as const;

type KeySet1Type = (typeof KEY_SET_1)[number];
type KeySet2Type = (typeof KEY_SET_2)[number];
type AllKeySetType = KeySet1Type | KeySet2Type;

const handleKey = (key: AllKeySetType) => {
  if (KEY_SET_1.includes(key)){ // <- Error here
    // Handle key set 1
  }else{
    // Handle key set 2
  }
}

I can make the error disappears by casting key as KeySet1Type but I am not sure if this is the best way to go about it.

>Solution :

I can make the error disappears by casting key as KeySet1Type
but I am not sure if this is the best way to go about it.

Indeed, it’s rather the type of KEY_SET_1 that is the problem there and should be cast to readonly string[]. But I suppose you’d want an actual type guard there, so that the type of key is strictly known to the compiler after the test, so here is how I’d rewrite it:

const KEY_SET_1 = ['A', 'B', 'C', 'D'] as const;
const KEY_SET_2 = ['E', 'F', 'G', 'H'] as const;

type KeySet1Type = (typeof KEY_SET_1)[number];
type KeySet2Type = (typeof KEY_SET_2)[number];
type AllKeySetType = KeySet1Type | KeySet2Type;

function isOfKeySet<KS extends AllKeySetType>(ks: readonly KS[], key: string): key is KS {
  return (ks as readonly string[]).includes(key);
}

const handleKey = (key: AllKeySetType) => {
  if (isOfKeySet(KEY_SET_1, key)) {
    key;  // (parameter) key: "A" | "B" | "C" | "D"
  } else {
    key;  // (parameter) key: "E" | "F" | "G" | "H"
  }
}

Link to playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading