Home > OS >  Typescript How to express if present should not be undefined
Typescript How to express if present should not be undefined

Time:11-27

How to express the below in typescript?

type LanguageName = "javascript" | "typescript" | "java" | "csharp"

type LanguageToWasmMap = {
  [key in LanguageName]: Exclude<LanguageName, key>
}

//I want the below to not throw error
const languageNameToWasmNameMap: LanguageToWasmMap = {
  "javascript" : "typescript"
}

//I want the below to throw error
const languageNameToWasmNameMapWithUndefined: LanguageToWasmMap = {
  "javascript" : undefined
} 

Typescript playground : Click Here

On thinking further, it makes sense to make the LanguageToWasmMap to be Optional as that it what it implies and do a runtime check for undefined.

CodePudding user response:

You can use Partial to tell TS that all the keys are not required.

    type LanguageName = "javascript" | "typescript" | "java" | "csharp"
    
    type LanguageToWasmMap = {
      [key in LanguageName]: Exclude<LanguageName, key>
    }
    
    //I want the below to not throw error
    const languageNameToWasmNameMap: Partial<LanguageToWasmMap> = {
      "javascript" : "typescript"
    }
    
    //I want the below to throw error
    const languageNameToWasmNameMapWithUndefined: LanguageToWasmMap = {
      "javascript" : undefined
    } 

playground

CodePudding user response:

You need to make it optional, and set exactOptionalPropertyTypes=true in tsconfig to disallow underfineds for optional

type LanguageName = "javascript" | "typescript" | "java" | "csharp"

type LanguageToWasmMap = {
  [key in LanguageName]?: Exclude<LanguageName, key> | never
}

//I want the below to not throw error
const languageNameToWasmNameMap: LanguageToWasmMap = {
  "javascript": "typescript"
}

//I want the below to throw error
const languageNameToWasmNameMapWithUndefined: LanguageToWasmMap = {
  "javascript": undefined
} 

Playground

CodePudding user response:

Using as seems to solve the issue. Not sure if this has any unintended side effects.

type LanguageName = "javascript" | "typescript" | "java" | "csharp"

type LanguageToWasmMap = {
  [key in LanguageName]: Exclude<LanguageName, key>
}

//I want the below to not throw error
const languageNameToWasmNameMap = {
  "javascript" : "typescript"
} as LanguageToWasmMap

//I want the below to throw error
const languageNameToWasmNameMapWithUndefined = {
  "javascript" : undefined
} as LanguageToWasmMap

Playground

CodePudding user response:

I guess you could make the the type generic, but you will need to specify the key twice:

    type LanguageName = "javascript" | "typescript" | "java" | "csharp"
    
    type LanguageToWasmMap<K extends LanguageName = LanguageName> = {
      [key in K]: Exclude<LanguageName, key>
    }
    
    //I want the below to not throw error
    const languageNameToWasmNameMap: LanguageToWasmMap<"javascript"> = {
      "javascript" : "typescript"
    }
    
    //I want the below to throw error
    const languageNameToWasmNameMapWithUndefined: LanguageToWasmMap = {
      "javascript" : undefined
    } 

Play

  • Related