Index signature with separate types for getters and setters

Viewed 180

Currently, it is possible to make setter support undefined/null and have non-undefined/non-null getter:

export interface IProperty<T> {
    get value(): T;
    set value(value: T | undefined);
}

// the following is ok with "strictNullChecks": true
const a: IProperty<string> = {value: ''};
a.value = undefined;
const b = a.value;
console.log(b);

I want to make a generic type that allows setting undefined for all properties of an object, see comment:

// this type works, but it also makes getter nullable :(
export type EditableObject<T> = {
    [K in keyof T]: EditableObject<T[K]> | undefined;
};

This looks bad, but we need such type to start using strictNullChecks in a large app.

export function editableScope<T>(item: T, block: (item: EditableObject<T>) => void): void {
    block(item);
}
1 Answers

No, you cannot currently get the behavior you're looking for (at the time of this writing, shortly after the release of TypeScript 4.4)

Your IProperty<T> type definition is using the support for separate write types on properties, also known as "variant accessors", as implemented by microsoft/TypeScript#42425 and introduced in TypeScript 4.3. But this only works on specific properties whose names are explicitly written out, like value in IProperty<T>. Variant accessors do not currently apply to index signatures or mapped types.

There is an existing feature request at microsoft/TypeScript#43826 which asks for support for such variant accessors for index signatures and mapped types. It's currently marked as "awaiting feedback", which means the TS team wants to hear about compelling use cases for such a feature. So anyone who cares about this might want to go there and describe their use case and give it a ... although it's not clear whether feedback of this sort will really affect when or if the feature gets implemented.

(I see that the OP of this question has already done this in the relevant GitHub issue, so this advice is unlikely to help the OP further, unfortunately. On the plus side, the OP should hopefully recognize this as being an authoritative and properly sourced answer. ‍♂️)

Related