Aundre
Aundre

Reputation: 382

Typescript Enforcing object literal is not working as expected

I am having an issue creating an object literal that enforces none primitive values.

When I attempt to map with primitives it works


interface StringMap {[key:string]: string }

let foo:StringMap = {
    "key_a": "bar",
    "key_b": 12 //works as expected Type 'number' is not assignable to type 'string'
}

But when I create my own object the map structure is not enforced.

class ChargeGroup{
}

interface ChargeGroupMap { [ key: string ]: ChargeGroup }
type ChargeGroupMap = { [ key: string ]: ChargeGroup } //tried this aswell

let foo:ChargeGroupMap = {
    "key_c": new ChargeGroup()
    "key_a": "bar", //no error
    "key_b": 12, //no error
}

current tsconfig.json

{
    "compilerOptions":{
        "target": "es6",
        "strict": true,
        "watch": true,
        "lib": ["dom", "es2018"],
        "types": [
            "dinero.js",
            "angular"
        ],
        "allowUmdGlobalAccess": true,
        "allowSyntheticDefaultImports": true,
        "removeComments": true,
        "alwaysStrict": true,
        "outFile": "../script/invoice.js",
        "noEmitOnError": true
    },
    "exclude": [
        "node_modules"
    ]
}

Any assistance on this issue would be greatly appreciated.

Upvotes: 0

Views: 98

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249786

You have an empty class. Typescript uses structural compatibility, so your empty class is equivalent to the {}, ie a type with no requirements. This means anything is assignable to it including number or string. As soon as you add a property to your class you will get errors.

class ChargeGroup{
    private notStructural!: unknown
}

interface ChargeGroupMap { [ key: string ]: ChargeGroup }


let foo:ChargeGroupMap = {
    "key_c": new ChargeGroup(),
    "key_a": "bar", //no error
    "key_b": 12, //no error
}

Play

Upvotes: 3

Related Questions