Search code examples
typescriptdictionaryobjectundefinedtype-safety

More useful typescript dictionary type: warn accessed item could be undefined


I want to be warned when accessing a dictionary that the value may be undefined. However I still want the type checking for when setting a value or accessing values through Object.values(). Is there any type in TypeScript that has those properties, or config option that gives that error?

type AlwaysPresent = {[id: string]: Date }

type PotentiallyUndefined = {[id: string]: Date | undefined }


const a: AlwaysPresent = {}
// good, no error
Object.values(a).filter(date => date.getTime())
// bad, no error, we have actually no assurance there is an item in the dictionary
console.log(a["2"].getTime())
// good, correctly errors
a["1"] = undefined


const b: PotentiallyUndefined = {}
// bad, errors - this is too cautious for my use case
Object.values(b).filter(date => date.getTime())
// good, correctly errors, we have no assurance there is an item in the dictionary and this correctly warns of such an event
console.log(b["2"].getTime())
// bad, no error, this is too lax as setting undefined should not be allowed
b["1"] = undefined

Solution

  • You might be interested in enabling the --noUncheckedIndexedAccess compiler flag introduced in TypeScript 4.1. This causes your original AlwaysPresent type to behave the way you want, at least for your example code:

    type AlwaysPresent = {[id: string]: Date }
    
    const a: AlwaysPresent = {}
    // good, no error
    Object.values(a).filter(date => date.getTime())
    // good, error
    console.log(a["2"].getTime())
    // good, correctly errors
    a["1"] = undefined
    

    Note that this compiler option is not included in the --strict compiler flag (and its name does not start with strict) because such behavior, while desirable for some code bases, does make certain operations less convenient. Turning it on with --strict would end up raising a lot of false positive warnings for existing code bases (specifically, a lot of for loops on arrays will start complaining about possibly undefined values).

    Playground link to code