typescript - Object frysa litterala objekttyper


Givet ett fryst objekt:

const obj = Object.freeze({a: 1, b:2});

dess typ är Readonly<{a:number, b:number}>, finns det något sätt att definiera detta så att dess typ är Readonly<{a:1, b:2}> istället, utan att behöva använda typkonvertering?

Anledningen till att jag vill ha detta är för att jag vill använda värdetyperna för att begränsa inputen till en annan funktion, t.ex.: function foo(input: 1 | 2)

Svar #1

function l<T extends number>(p: T ): T { 
   return p;
}
const c = { a: l(1), b: l(2) };
// const fc: Readonly<{ a: 1; b: 2; }>
const fc = Object.freeze(c);

eller

function lc<T extends number>(p: { [k: string]: T }) : { [k: string]: T } { 
    return p;
}
// const t1: { [k: string]: 1 | 2 | 3; }
const t1 = lc({ a: 1, b: 2, c: 3 });

Svar #2

I den kommande versionen av TypeScript (3.4) kommer du att kunna göra:

const obj = Object.freeze({ a: 1, b: 2 } as const); // { radonly a: 1, readonly b: 2 }