Io-ts interface for properties with unknown keys

5k Views Asked by At

I'm trying to create an io-ts interface of the following:

export interface myInterface {
  [key:string]?: string | undefined | null
}

I want to turn this into the io-ts equivalent. The end goal is to combine it with another existing io-ts interface:

export const MyOtherInterfaceV = t.interface({
  requiredProp1: ValidString// custom type, checks string is populated
  requiredProp2: ValidString
  // All other fields marked as required
})

export type MyOtherInterface = t.TypeOf<typeof MyOtherInterfaceV>;

The idea is I need a type to represent a payload which will have some fields we require and must be valid, and some that we don't know about and can be optional. We want to combine these for use later on in processing, eventually being stored in dynamodb.

2

There are 2 best solutions below

0
On

Probably the most close to myInterface in io-ts is t.UnknownRecord

export const MyOtherInterfaceV = t.interface({
  requiredProp1: t.string,
  requiredProp2: t.string
})

const MyOtherInterface = t.intersection([ t.UnknownRecord, MyOtherInterfaceV ]);
2
On

I think the answer you're looking for is record:

const myInterfaceCodec = t.record(t.string, t.union([t.string, t.undefined, t.null]));
export type MyInterface = t.TypeOf<typeof myInterfaceCodec>;

=> type MyInterface = { [x: string]: string | null | undefined; }

Your use case:

const myInterfaceV = t.record(t.string, t.union([t.string, t.undefined, t.null]));
export type MyInterface = t.TypeOf<typeof myInterfaceV>;

const myOtherInterfaceV = t.intersection([
    t.type({
        requiredProp1: t.string,
        requiredProp2: t.string
    }),
    myInterfaceV
]);
export type MyOtherInterface = t.TypeOf<typeof myOtherInterfaceV>;

const a: MyOtherInterface = {
    requiredProp1: "string",
    requiredProp2: "string2"
};

const b: MyOtherInterface = {
    requiredProp1: "string",
    requiredProp2: "string2",
    optionalProp1: "hello",
    optionalProp2: "world"
};