Skip to content
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

Initial support of traits in Typescript #525

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bjarkehs
Copy link

In attempt to fix #524 this adds a very simple form of support for traits in Typescript.

Currently missing any handling of trait properties.

Downside of this is that it currently does not handle the traits' added properties.

I attempted to type the trait function and FlattenFactoryMethods so I could filter out the trait and instead add the trait's properties. But I couldn't figure it out.

I attempted something like:

// Extract factory method return values from a factory definition
type FlattenFactoryMethods<T> = {
  [K in keyof T]: T[K] extends (n: number) => infer V
    ? V
    : T[K] extends (data: {}) => Trait<infer U>
    ? U
    : T[K];
};

type Trait<T extends {} = {}> = T & { __isTrait__: true };

This is not part of the PR since I couldn't get it working.

@samselikoff
Copy link
Contributor

@dfreeman @chriskrycho @zoltan-nz @jamescdavis If any of you have any spare cycles to take a look at this I'd appreciate it!

If not feel free to ignore :)

@samselikoff
Copy link
Contributor

@bjarkehs thanks for opening this!

@dfreeman
Copy link
Contributor

I should have some time to look at this later this week—first I'll have to read up on how traits actually work 😅

@samselikoff
Copy link
Contributor

Oh man traits are the bomb. Similar to FactoryBot traits if you've ever used em.

https://miragejs.com/docs/main-concepts/factories/#traits

@jamescdavis
Copy link
Contributor

I'm hoping to look at this week as well. And I'm pretty familiar with traits. 😉

@dfreeman
Copy link
Contributor

Just a quick update on this: I spent some time over the weekend puzzling out how to type the way traits work. It seems like it's possible, but... complicated 😄

I'll coordinate with @jamescdavis and see if we can't get a cleaned up version put together to propose here

@samselikoff
Copy link
Contributor

Cool – feel free to propose new API if it helps too (like we did with createServer)

@thedaviddias
Copy link

@jamescdavis @dfreeman any update in adding trait and association?

@yekver
Copy link

yekver commented Sep 18, 2020

really waiting for this PR!

@MrLoh
Copy link

MrLoh commented Dec 21, 2020

so am I any progress on maybe at least not throwing a type error for this anymore

@rubenmoya
Copy link

Anything we can do to push this forward? Even without having types in the traits properties at least it won't throw an error when trying to use traits.

@dfreeman
Copy link
Contributor

dfreeman commented Jan 8, 2021

I picked this up to work on it over the holidays and wound up a little stumped by the change that landed in #695 and what problem it was addressing. Had a quick conversation in the #typescript channel about it and Sam suggested checking with the author of the PR.

@NLincoln can you offer any insight into that fix? I see you linked to some example code that doesn't work because factories don't understand ES getters, but I don't quite understand how the types change addresses that. I'm also happy to chat on Discord if that would be easier than going back and forth on issue comments 🙂

@josemarluedke
Copy link

Looking forward to having TypeScript support for traits!

@@ -115,6 +115,9 @@ declare module "miragejs" {
export function hasMany<K extends string>(
options?: RelationshipOptions
): HasMany<K>;

/** Declares traits for Factory */
export function trait<Data>(data: Data): Data;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to also add type for afterCreate method?

@wagenet
Copy link
Contributor

wagenet commented Dec 2, 2021

@dfreeman it definitely seems incorrect to me as well. See #695 (comment)

@jasikpark
Copy link
Contributor

jasikpark commented Mar 9, 2022

Wouldn't

/** Declares traits for Factory */
  export function trait<Data>(data: Data): Data & { __isTrait__: true };

be slightly more correct, since trait is just adding that value to Data?

or

type Trait<T extends {} = {}> = T & { __isTrait__: true };
/** Declares traits for Factory */
  export function trait<Data>(data: Data): Trait<Data>;

a la @bjarkehs's original snippet in the PR description

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Trait and association not available in Typescript