In TypeScript, I have a Record like this:
const entityTypeExemptPayeeCodeMap: Record<EntityType, readonly PayeeCode[]> = {
[EntityType.Smllc]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.Llc]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.CCorp]: [1, 2, 3, 4, 5, 6, 7, 9, 11, 12],
[EntityType.SCorp]: [1, 2, 3, 4, 5, 6, 7, 9, 11, 12],
[EntityType.Partnership]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.TrustEstate]: [1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13],
[EntityType.Other]: [1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13],
} as const;
I'd like to get a number union type from one of the arrays inside the Record. I thought this may work:
type SmllcExemptPayeeCodes = typeof entityTypeExemptPayeeCodeMap[EntityType.Smllc]
But that just gives me a type of readonly PayeeCode[]
and not a union of the values in the array.
If I make entityTypeExemptPayeeCodeMap
not be a Record, like this:
const entityTypeExemptPayeeCodeMap = {
[EntityType.Smllc]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.Llc]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.CCorp]: [1, 2, 3, 4, 5, 6, 7, 9, 11, 12],
[EntityType.SCorp]: [1, 2, 3, 4, 5, 6, 7, 9, 11, 12],
[EntityType.Partnership]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.TrustEstate]: [1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13],
[EntityType.Other]: [1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13],
} as const;
then SmllcExemptPayeeCodes
becomes a union as I would expect. Is there any way to keep the Record type for entityTypeExemptPayeeCodeMap
and still retrieve a union?
In the above examples, EntityType is:
enum EntityType {
Smllc = "smllc",
Llc = "llc",
CCorp = "cCorp",
SCorp = "sCorp",
Partnership = "partnership",
TrustEstate = "trustEstate",
Other = "other",
}
PayeeCode is:
type PayeeCode = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
CodePudding user response:
I thought this may work:
type SmllcExemptPayeeCodes = typeof entityTypeExemptPayeeCodeMap[EntityType.Smllc]
...
If I make
entityTypeExemptPayeeCodeMap
not be aRecord
, like this:...thenSmllcExemptPayeeCodes
becomes a union as I would expect.
That's odd, I'd expect you to need [number]
on that.
Is there any way to keep the Record type for
entityTypeExemptPayeeCodeMap
and still retrieve a union?
I don't think so, TypeScript will defer to what you've told it; but you can use an intermediate variable (codeMap
in this example):
const codeMap = {
[EntityType.Smllc]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.Llc]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.CCorp]: [1, 2, 3, 4, 5, 6, 7, 9, 11, 12],
[EntityType.SCorp]: [1, 2, 3, 4, 5, 6, 7, 9, 11, 12],
[EntityType.Partnership]: [1, 2, 3, 4, 6, 7, 11, 12],
[EntityType.TrustEstate]: [1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13],
[EntityType.Other]: [1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13],
} as const;
const entityTypeExemptPayeeCodeMap: Record<EntityType, readonly PayeeCode[]> = codeMap;
type SmllcExemptPayeeCodes = (typeof codeMap)[EntityType.Smllc][number];
// ^? type SmllcExemptPayeeCodes = 1 | 2 | 3 | 4 | 6 | 7 | 11 | 12
Then if you want things to only use the Record
version, only expose entityTypeExemptPayeeCodeMap
to other code and not codeMap
.