Created
February 10, 2023 20:06
-
-
Save stephencweiss/e10f5a072e06b7e2703c8d228bfaf2fb to your computer and use it in GitHub Desktop.
io-ts Partial records
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { map } from 'fp-ts/Record'; | |
import * as t from 'io-ts'; | |
export const StandardCodec = t.type({ fields: t.string }); | |
export type Standard = t.TypeOf<typeof StandardCodec>; | |
// export const OriginalCodec = t.type({ original: t.string }); | |
// export type Original = t.TypeOf<typeof OriginalCodec>; | |
export const partialRecord = <K extends string, T extends t.Any>( | |
k: t.KeyofType<Record<string, unknown>>, | |
type: T, | |
): t.PartialC<Record<K, T>> => t.partial(map(() => type)(k.keys)); | |
const SupportedEnvCodec = t.keyof({ prod: null, qa: null, dev: null }); | |
type SupportedEnv = t.TypeOf<typeof SupportedEnvCodec>; | |
type ProdEnv = Extract<SupportedEnv, 'prod'>; | |
const ProdEnvCodec: t.Type<ProdEnv> = t.literal('prod'); | |
type OtherEnv = Exclude<SupportedEnv, 'prod'>; | |
const OtherEnvCodec: t.KeyofType<Record<OtherEnv, unknown>> = t.keyof({ qa: null, dev: null }); | |
export const StrictExtendedCodec = t.intersection([ | |
t.record(ProdEnvCodec, StandardCodec), | |
t.record(OtherEnvCodec, StandardCodec)]); | |
export type StrictExtended = t.TypeOf<typeof StrictExtendedCodec>; | |
const LooseExtendedCodec = partialRecord<OtherEnv, typeof StandardCodec>( | |
OtherEnvCodec, StandardCodec, | |
); | |
export const ExtendedCodec = t.intersection([ | |
t.record(ProdEnvCodec, StandardCodec), | |
LooseExtendedCodec]); | |
export type Extended = t.TypeOf<typeof ExtendedCodec>; | |
// Errors | |
const strict: StrictExtended = { | |
prod: {fields: ''}, | |
dev: {fields: ''}, | |
}; | |
// Compiles | |
const loose: Extended = { | |
prod: { | |
fields: '', | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment