Reputation: 79
I'm trying to build a simple abstraction that lists patches to an object.
type MyObject = {
attributeA: string;
attributeB: boolean;
attributeC: number;
};
type MyObjectKeys = keyof MyObject;
type Difference<Key extends MyObjectKeys = MyObjectKeys> = {
// The value of this attribute should determine
// the type of the old and new value.
key: Key;
oldValue: MyObject[Key];
newValue: MyObject[Key];
};
type Patch = {
patches: Difference[];
};
const patch: Patch = {
patches: [
{
key: 'attributeB',
// Should be inferred as boolean.
oldValue: '',
// Both should have the same inferred type.
newValue: 9,
},
],
};
I want oldValue
and newValue
to be typed according to the given key
.
Unfortunately, as stated in the code comments, it's not working.
I'm grateful for any advice!
Upvotes: 0
Views: 434
Reputation: 1337
Type inference doesn't work like this. You should create some helpers:
type MyObject = {
attributeA: string;
attributeB: boolean;
attributeC: number;
};
type MyObjectKeys = keyof MyObject;
type Difference<Key extends MyObjectKeys = MyObjectKeys> = {
// The value of this attribute should determine
// the type of the old and new value.
key: Key;
oldValue: MyObject[Key];
newValue: MyObject[Key];
};
type Patch = {
patches: Difference[];
};
function createPatch<T extends MyObjectKeys>(key: T, oldValue: MyObject[T], newValue: MyObject[T]): Difference<T> {
return {
key,
oldValue,
newValue,
};
}
function addPatch<T extends MyObjectKeys>(key: T, oldValue: MyObject[T], newValue: MyObject[T], patch: Patch) {
patch.patches.push(createPatch(key, oldValue, newValue));
}
const patch: Patch = {
patches: [createPatch('attributeB', '', 9), createPatch('attributeA', '', 'newVal')],
};
addPatch('attributeC', 0, 10, patch);
Upvotes: 1