Open
Description
Is there a method of inferring typescript types of getProperties?
Similar to @sinclair/typebox's Static and zod's infer
I have created my own limited and simple version, it can infer the concrete typescript types from a schema, and it seems to work okay but before continuing further, I thought I would share it to see if a solution already exists, or if anyone can offer feedback.
type NumberTypes = NumberConstructor | number | 'port' | 'int' | 'nat' | 'duration' | 'timestamp';
type BooleanTypes = BooleanConstructor | boolean;
type UnknownTypes = '*';
type StringTypes = StringConstructor | string | 'url' | 'email' | 'ipaddress' | 'nat';
type InferredProps<T> = {
[k in keyof T]-?: T[k] extends SchemaObj
? T[k]['format'] extends NumberTypes
? number
: T[k]['format'] extends BooleanTypes
? boolean
: T[k]['format'] extends UnknownTypes
? unknown
: T[k]['format'] extends StringTypes
? string
: // eslint-disable-next-line @typescript-eslint/ban-types
T[k]['format'] extends Function
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
ReturnType<T[k]['format']>
: T[k]
: InferredProps<T[k]>;
// eslint-disable-next-line @typescript-eslint/ban-types
} & {};
Given a schema like:
const testSchema = {
number: {
format: Number,
default: null,
env: 'SOME_VAR',
},
port: {
format: 'port' as const,
default: null,
env: 'SOME_VAR',
},
duration: {
format: 'duration' as const,
default: null,
env: 'SOME_VAR',
},
url: {
format: 'url' as const,
default: null,
env: 'SOME_VAR',
},
string: {
format: String,
default: null,
env: 'SOME_VAR',
},
bool: {
format: Boolean,
default: null,
env: 'SOME_VAR',
},
nested: {
string: {
format: String,
default: null,
env: 'SOME_VAR',
},
bool: {
format: Boolean,
default: null,
env: 'SOME_VAR',
},
},
};
It can be used like
type ConfigProps = InferredProps<typeof testSchema>;
const config = convict(testSchema);
const configPropsInferred = config.getProperties() as ConfigProps;
// ^? const config: {number: number, port: number, duration: number, url: string, string: string, bool: boolean, nested: {string: string, bool: boolean}}
While using getConfig returns the correct keys, it fails to infer the type and just returns null
const configProps = config.getProperties();
// ^? const configProps: {number: null, port: null, duration: null, url: null, string: null, bool: null, nested: {string: null, bool: null}}
Any feedback welcome!
Metadata
Metadata
Assignees
Labels
No labels