Home > Back-end >  Why is TypeScript Not Checking the Type of Dynamic Key Object Fields
Why is TypeScript Not Checking the Type of Dynamic Key Object Fields

Time:12-15

Why does TypeScript accept the definition of seta when it does not return objects of type A?

type A = {
    a: '123',
    b: '456'
}

// Returns copy of obj with obj[k] = '933'
function seta<K extends keyof A>(k: K, obj: A): A {
    return {
        ...obj,
        [k]: '933'
    }
}

const w: A = seta('a', {
    a: '123',
    b: '456'
})

// now w = {a: '933', b: '456'}

https://tsplay.dev/wEGX4m

CodePudding user response:

It's accepted because if you hover on [k]: '933', it says

(parameter) k: K extends keyof A

Which means you're returning a property that's extended from the return type, which is allowed.

When you declare that an object must be of an interface, you are saying that it must have at least those properties, not only those properties.

CodePudding user response:

This looks like a bug or limitation in TypeScript; see microsoft/TypeScript#37103 (labeled a bug) or microsoft/TypeScript#32236 (labeled "needs investigation").

When you spread properties into an object literal and then add a computed property, it seems that TypeScript will completely ignore the computed property unless the computed key is of a single, specific, literal type (not a union of literals, and not a generic type parameter constrained to a string literal):

function testing<K extends "a" | "b">(a: "a", x: string, y: "a" | "b", z: K) {
    const someObject = { a: "v" } // { a: string }
    const objA = { ...someObject, [a]: 0 } // { a: number }            
  • Related