-
Notifications
You must be signed in to change notification settings - Fork 642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Typescript] Overriden model props get 'never'/'multiple implementation' typings #1403
Comments
I suspect we should do the same for |
The sandbox doesn't seem to contain any code. But... I actually thought overriding props was forbidden 🤔 . Or at least it should be imho, as changing the type of a property breaks the contract of the type. (if X.y is declared as string, action X.z assumes it is a string, and then X.props() redeclares it as number, you'd be breaking X.z). So I think it is technically correct that you end up with a |
I'm running into this while building models that are shared between a server and client project. I'd like each sub-project to be able to add project specific views/actions to the base shared models. This works but per above posts the types are wrong, we get an intersection of the redefined properties instead of overwriting them. For example:
|
We use the following function to overcome the topic issue: export type IOverridenModelType<BASE extends IAnyModelType, PROPS extends ModelProperties> = BASE extends IModelType<
infer P,
infer O,
infer CC,
infer CS
>
? IModelType<Omit<P, keyof PROPS> & PROPS, O, CC, CS>
: never;
export function OverrideContractPorperties<BASE extends IAnyModelType, PROPS extends ModelProperties>(
contact: BASE,
props: PROPS
): IOverridenModelType<BASE, PROPS> {
return contact.props(props) as IOverridenModelType<BASE, PROPS>;
} Usage: const FooBase = types.model('FooBase', {
text: types.string,
number: types.number,
overriden: types.string,
});
const Foo = OverrideContractPorperties(FooBase, {
overriden: types.array(types.string),
});
// just for example, to show the type output
const foo = {} as unknown as Instance<typeof Foo>;
foo.overriden; // IMSTArray<ISimpleType<string>> & IStateTreeNode<IArrayType<ISimpleType<string>>> Hope this helps those who come here with the same problem. |
Hey @k-g-a - I really appreciate the in-depth answers and examples you put together here. This thread has been inactive for a while, so I'm inclined to close it out if I don't hear otherwise in the next two weeks or so. Thanks, y'all! |
Hey @coolsoftwaretyler! Thanks for asking. Too my mind, we could mention somewhere in the docs the @mweststrate's note about the fact, that props overriding is not meant to be done. Alongside with that note we could mention one possible workaround from my last post. A more ideal solution would be to leave the current approach "as is" and jsut add No matter the final decision, I don't mind closing this issue. |
Thanks for the follow up, @k-g-a. I'm going to toss a I'm going to leave this open for now. I appreciate you getting back to me! |
Bug report
Sandbox link or minimal reproduction code
https://codesandbox.io/s/goofy-dewdney-u7sbo
Describe the expected behavior
Overriding prop via
ModelType.props(NEW_PROPS)
updates it's typings.Describe the observed behavior
We get union type, which ends up in
never
for simple types (Problem #1 at sandbox) ormultiple implementations
for complex ones (Problem #2 at sandbox).It seems like instead of doing (at model.ts):
We should do something like:
The
Omit<...>
part is added. But my quick experiment ended up with dozens of type errors.I can make a PR if any solution is found.
The text was updated successfully, but these errors were encountered: