I have a registry of "models" and when I select a model from the registry, and call a method on it, TypeScript expects an intersection of the parameters across all registered models.
For brevity, I've reproduced this bug with a dummy method "getName".
export class Model<N extends string> {
public name: N;
constructor(name: N) {
this.name = name;
}
public getName = (options: { __type: N }) => options.__type;
}
export const Book = new Model("Book");
export const User = new Model("User");
export const modelRegistry = { Book, User };
export type ModelRegistry = typeof modelRegistry;
export const makeModel = <N extends keyof ModelRegistry>(name: N) => (
options: Parameters<ModelRegistry[N]["getName"]>[0],
) => {
const model = modelRegistry[name];
return model.getName(options); // <-- bug: TS expects this to be { __type: User } & { __type: Book }
};

makeModelsupposed to be called?makeModelis really just an artifact of my real code, you can ignore its naming. In practice, I have external data streaming in, and I transform that data based on the__typeproperty. I fetch data from an endpoint, convert it to a schema (usingio-ts), and then convert it to a "model" (it gains certain methods depending on__type).