Reputation: 4551
Record
is defined as follows:
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
It is defined such that for a Record<A, B>
for every A
there is a B
.
But how do I define that there might not be a B
for every A
?
If I use Partial<Record<A, B>>
we would say for every A
there is either B
or undefined
. But I don't want to except undefined
as value:
type A = 'A1' | 'A2' | 'A3';
// Complains about "Type '{ A1: string; }' is missing the following properties from type 'B': A2, A3(2739)"
// But I want to be allowed to ommit any value of A
type B = Record<A, string>;
const fooB: B = {
A1: 'value for A1'
}
// Allows to omit properties but also allows undefined as value, which I don't want.
type C = Partial<Record<A, string>>;
const fooC: C = {
A1: 'value for A1',
A2: undefined // Should not be allowed!
}
( Playground )
To disallow undefined
makes a difference, for example when using Object.keys()
:
Object.keys({A2: undefined})
['A2']
It is still expected and fine that {}.A2 === undefined
.
--exactOptionalPropertyTypes
also can't be used as it would affect the whole codebase (If I am not mistaken also types from external dependencies used).
Upvotes: 0
Views: 92
Reputation: 11978
It sounds like you want a type where every A
is explicitly mapped to some output, but the output can be either B
or undefined.
So you would want to use:
Record<A, B|undefined>
Upvotes: -1