I'm writing a library with TypeScript. It's meant to be a super-set of a configuration language, and itself configurable.
In a particular context, I want to declare a class with an object of essentially any shape, which will be converted to the expected shape by a function which the user of the library can provide (and for which I provide a default). The super-simplified version:
// Defined by a library user
interface Input {
myName: string;
};
// Defined by my library, and non-configurable
interface Output {
name: string;
};
// Defined by a library user (with a default fallback)
const mappingFunc = (input: Input): Output => ({
name: input.myName
});
new MyClass({ myName: "Whatever" }, mappingFunc);
Within the class, the mappingFunc
will generate the object the class manipulates (and a default mapping func will just accept and return an output-shaped object), but this pattern allows users of the lib to specify a mapping they want, and declare the object shape they want passed in, so long as the mapping function returns an output-shaped object.
Any idea how to do this, or if it's possible? I tried the below, but no dice. The type checker did not detect that the input didn't match the input interface, and in fact didn't check the input at all.
// Defined by my library
interface Output {
name: string;
};
// Defined by my library
const makeClass = (mappingFunc: (unknown) => Output) =>
class SpecifiedMyClass(input: unknown) {
// Uses mappingFunc internally
}
return SpecifiedMyClass
}
// Below defined by user of the library
interface Input {
myName: string;
};
const typedMappingFunc = (input: Input): Output => ({
name: input.myName
});
const MyClass = makeClass(typedMappingFunc);
new MyClass({ myName: "Whatever" });
What'd I'm trying to do is to able to declare the type of the input
arg into the MyClass
be defined dynamically. Any ideas? Hard to explain.
CodePudding user response:
// Defined by my library
const makeClass = <T extends unknown>(mappingFunc: (T) => Output) =>
class SpecifiedMyClass(input: T) {
// Uses mappingFunc internally
}
return SpecifiedMyClass
}
Maybe I didn't understand the problem correctly, however I think this should solve your problem.