-
Notifications
You must be signed in to change notification settings - Fork 25
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
Generic refs #248
Comments
Just wondering, how is that different from
? I'm confused because with references you usually set the type as a type argument, not through inference. |
Although the added value might not be as significant as for generic models, wouldn't it be nice to be able to have: const genericModelRef = rootRef("GenericModel", <T>() => ({
// ...
}))
const m = new GenericModel({ value: 1 }) // e.g. GenericModel<number> (inferred at construction time)
const mref = genericModelRef(m) // e.g. Ref<GenericModel<number>> (inferred)
|
And from what part of the options to rootRef would it infer the type from? (both are optional) export interface RootRefOptions<T extends object> {
/**
* Must return the ID associated to the given target object, or `undefined` if it has no ID.
* If not provided it will try to get the reference id from the model `getRefId()` method.
*
* @param target Target object.
*/
getId?: RefIdResolver
/**
* What should happen when the resolved value changes.
*
* @param ref Reference object.
* @param newValue New resolved value.
* @param oldValue Old resolved value.
*/
onResolvedValueChange?: RefOnResolvedValueChange<T>
} Or you mean it should be inferred from the parameter to the constructor? though in that case I guess it wouldn't be type checked if you pass a wrong type. const m = new GenericModel({ value: 1 }) // e.g. GenericModel<number> (inferred at construction time)
const mref = someOtherRef(m) // would infer to Ref<GenericModel<number>>, but we wanted those kind of refs to only support other models |
Maybe a middle ground? const genericModelRef = rootRef<GenericModel<any>>("GenericModel", {
// ...
})
const ref = genericModelRef(new GenericModel({value: 1})) // creates a Ref<GenericModel<number>>
const invalidRef = genericModelRef(new SomeOtherModel()) // error since SomeOtherModel does not extend GenericModel<any> don't know if it is even possible yet though |
Just checked, apparently it is :) |
Good? test("generic typings", () => {
@model("GenericModel")
class GenericModel<T1, T2> extends Model(<U1, U2>() => ({
v1: prop<U1 | undefined>(),
v2: prop<U2>(),
v3: prop<number>(0),
}))<T1, T2> {}
const genericRef = rootRef<GenericModel<any, any>>("genericRef")
const ref = genericRef(new GenericModel({ v1: 1, v2: "2" }))
assert(ref, _ as Ref<GenericModel<number, string>>)
const genericRef2 = rootRef<GenericModel<string, number>>("genericRef2")
// @ts-expect-error
genericRef2(new GenericModel({ v1: 1, v2: "2" }))
}) |
PR #255 |
Perfect, that's an even better solution! Exactly what I was hoping to achieve. Thank you very much as always! 🙂 |
out in 0.59.0 |
How about making refs generic as well (if possible) like we made models generic (#239, #242, 9be6e0f)? This would be useful for creating refs of generic models, so the generics can be passed down, e.g.:
Of course the same for custom refs.
The text was updated successfully, but these errors were encountered: