I have two properties on an object being passed into a function. I want to constrain the deps property on one object's properties to be a key of the other object.
E.g.:
const config = {
modules: {
bar: {
baz: true,
deps: ['foo', 'notADep'],
factory: () => Promise.resolve(() => {}),
},
},
services: {
foo: { factory: () => Promise.resolve(() => {}) },
},
};
In the above config, foo is valid, but notADep is not valid.
Here's my code:
function createApp<T extends Config>(config: T) {}
export type Service<T> = {
factory: () => Promise<() => void>;
deps?: (keyof T & string)[] | undefined;
}
export type Services<T = any> = Partial<Record<keyof T, Service<any>>>;
export type Modules<T = any> = Record<string, {
baz: boolean,
} & Service<keyof T>>
interface Config {
modules: Modules;
services: Services;
}
I'm getting an error on the config parameter that
Argument of type '{ modules: { bar: { baz: boolean; deps: string[]; factory: () => Promise<() => void>; }; }; services: { foo: { factory: () => Promise<() => void>; }; }; }' is not assignable to parameter of type 'Config'.
Types of property 'modules' are incompatible.
Type '{ bar: { baz: boolean; deps: string[]; factory: () => Promise<() => void>; }; }' is not assignable to type 'Modules<any>'.
Property 'bar' is incompatible with index signature.
Type '{ baz: boolean; deps: string[]; factory: () => Promise<() => void>; }' is not assignable to type '{ baz: boolean; } & Service<string | number | symbol>'.
Type '{ baz: boolean; deps: string[]; factory: () => Promise<() => void>; }' is not assignable to type 'Service<string | number | symbol>'.
Types of property 'deps' are incompatible.
Type 'string[]' is not assignable to type '("toString" | "valueOf")[]'.
Type 'string' is not assignable to type '"toString" | "valueOf"'.