-
Notifications
You must be signed in to change notification settings - Fork 6
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
Inherit Ent properties in pattern interface #1739
Comments
Ok, hear me out, I've thought about this some more and I have some ideas on how to make patterns even better. So, instead of converting to |
I say leave // some_pattern_base.ts
// Don't export
interface ISomePattern extends Ent {
someField: string;
} // some_pattern.ts
export interface ISomePattern {
myCustomFunc: () => void;
} TS should just merge the two, so everywhere it will treat the interface as export interface ISomePattern extends Ent {
someField: string;
myCustomFunc: () => void;
} This works because we know the pattern file will always include the base file first. Kinda hacky, but it saves backwards compatibility and lets you customize pattern interfaces. |
It’s mixins because IIRC, you cannot inherit from multiple base classes in
typescript/javascript.
Can you come up with examples of your proposal in a gist/playground so that
it’s more concrete and less abstract?
…On Fri, Feb 2, 2024 at 07:52 Stefan Parker ***@***.***> wrote:
Ok, hear me out, I've thought about this some more and I have some ideas
on how to make patterns even better.
So, instead of converting to type, leave it an interface and do interface
ISomePattern extends Ent (I thought Ent was a class, not an interface).
Now, convert this whole mixin to a "base" similar to how it's done with
ents, so you would have SomePatternMixinBase. Then you can extend the
base with an empty SomePatternMixin which will allow you to write custom
methods on patterns.
—
Reply to this email directly, view it on GitHub
<#1739 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACS2VNYWVZQA2DTY7NUECXTYRUDSPAVCNFSM6AAAAABCHIFCY6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMRUGE2DSOBTHA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
It'll still be a mixin, but you'll be able to add custom fields/methods to the mixin. https://gist.github.com/Swahvay/bc91257bdd89371e5b77bf12c7359705 |
https://github.com/lolopinto/ent/compare/fix-1739?expand=1 kinda works. can't reference base methods in other interface. thoughts? |
Yeah, I realized there's no need to use the special overriding instance name hack here. You can simply name the original instance |
And it'll still be backwards compatible. |
Also, the base interface should |
in practice, those set of changes don't work because FeedbackMixin doesn't have the methods IFeedbackBase requires. You should play with the entire chain in case i'm missing something |
You are missing a couple things. For one, you need to change the import { Data, Ent, Viewer } from '@snowtop/ent';
import { Country, convertNullableCountry } from '../types';
type Constructor<T extends Ent = Ent> = new (...args: any[]) => T;
export interface ILocationBase extends Ent {
address: string | null;
address2: string | null;
city: string | null;
state: string | null;
postalCode: string | null;
country: Country | null;
}
function extractFromArgs<TViewer extends Viewer, TData extends Data>(
args: any[],
): { viewer: TViewer; data: TData } {
if (args.length !== 2) {
throw new Error('args should be length 2');
}
return {
viewer: args[0],
data: args[1],
};
}
export function LocationBaseMixin<T extends Constructor>(BaseClass: T) {
return class LocationBaseMixin extends BaseClass implements ILocationBase {
readonly address: string | null;
readonly address2: string | null;
readonly city: string | null;
readonly state: string | null;
readonly postalCode: string | null;
readonly country: Country | null;
constructor(...args: any[]) {
super(...args);
const { data } = extractFromArgs(args);
this.address = data.address;
this.address2 = data.address_2;
this.city = data.city;
this.state = data.state;
this.postalCode = data.postal_code;
this.country = convertNullableCountry(data.country);
}
};
} import { Ent } from '@snowtop/ent';
import { ILocationBase, LocationBaseMixin } from './location_base';
type Constructor<T extends Ent = Ent> = new (...args: any[]) => T;
export function isLocation(ent: Ent): ent is ILocation {
const o = ent as ILocation;
return (o.isLocation && o.isLocation()) ?? false;
}
export interface ILocation extends ILocationBase {
isLocation(): boolean;
}
export function LocationMixin<T extends Constructor>(BaseClass: T) {
return class LocationMixin
extends LocationBaseMixin(BaseClass)
implements ILocation
{
isLocation() {
return true;
}
};
} |
I guess you also need to update implementations: export class BarnInfoBase
extends LocationMixin(class {} as (new (...args: any[]) => Ent))
implements Ent<BarnlogViewer>, ILocation
{
...
} (You could also put the Ent-fields inside the anonymous class, but I feel like that would be much harder to read and wouldn't really add anything) |
I think your error was also stemming from this: should be |
i haven't had a chance to test the other things but it can't implement IFeedbackBase because it doesn't have implementations for everything else |
I think your Location Pattern needs some edges so we can confirm that we're on the same page wrt behavior when those methods are missing from FeedbackMixin |
You're right. You need to make one more subtle change. Each file needs to have its
|
almost there ent/examples/simple/src/ent/generated/mixins/feedback/actions/feedback_builder.ts Lines 28 to 46 in 8f1f481
|
I'm confused a little bit because I'm not getting any errors in my patterns with edges. What is the problem you're seeing? |
would you consider this one fixed in v0.2.0? |
I believe so. I've even started using it already. I think maybe a v0.3 feature might be to be able to add GraphQL fields to the pattern, but that would obviously require much more work and it obviously works the same by putting the fields on each ent. |
It would also be nice if these patterned ents implemented interfaces in graphQL schemas, so that I could just do ... on MyPattern {
someField
} |
Closing this in favor of more specific lingering issues with patterns. Specifically #1832. |
Instead of doing
If you convert it to a type you can do
So that typing it as
ISomePattern
will still get youid
andviewer
. Plus it'll work in places that expect ents.The text was updated successfully, but these errors were encountered: