Giter Site home page Giter Site logo

shoooe / derive Goto Github PK

View Code? Open in Web Editor NEW
26.0 26.0 1.0 7.46 MB

Library to derive a TypeScript type from another.

Home Page: https://www.npmjs.com/package/@shoooe/derive

License: MIT License

TypeScript 100.00%
derive graphql types typescript

derive's People

Contributors

shoooe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

coridyn

derive's Issues

Support for GraphQL-esque aliases

Problem

GraphQL supports aliases in the form:

query ($startOfWeek: DateTime!, $startOfLastWeek: DateTime!) {
    something {
        id
        startOfWeekValue: valueAt(at: $startOfWeek)
        startOfLastWeekValue: valueAt(at: $startOfLastWeek)
    }
}

Currently there's no good way to alias another field. If the field you are trying to alias is a scalar type then you can make it work via:

type Result = Derive<Something, {
    id: Auto;
    startOfWeekValue: Something["valueAt"];
    startOfLastWeekValue: Something["valueAt"];
}

but this won't work well with arrays and nested objects. It also doesn't infer optionality correctly because you are forced to specify the field as non optional.

You can probably make it work via a nested Derive for arrays and objects (haven't tried it yet), but that's cumbersome at best.

Shapes shouldn't require at least 1 field from the base type

With the introduction of aliases it does sometimes make sense for a shape to only have non-base-type fields.
The following should but currently doesn't compile:

type User = { id: number; }
type SomeShape = Shape<User, {}>; // doesn't compile
type SomeOtherShape = Shape<User, { extra: Alias<User, 'id'> }>; // also doesn't compile

Is there a better way to combine two shapes?

Use case

Say component A has a user definition:

type UserProp = Derive<User, { ... }>;

and the parent component wants to reuse that shape in its own type definition:

type BookProp = Derive<Book, {
    id: Auto;
    ...
    author: [HERE];
}>

Current solution

The current solution looks like this:

export type UserShape = Shape<User, { ... }>;
type UserProp = Derive<User, UserShape>;

and the parent component wants to reuse that shape in its own type definition:

type BookShape = Shape<Book, {
    id: Auto;
    ...
    author: UserShape & {
        id: Auto; // optional expansion
    };
}>
type BookProp = Derive<Book, BookShape>;

Problem

The solution might seem ok, but in practice this makes everything very verbose because for each type you want to derive you have to have 2 types (a shape and the actual derived type).

This is quite annoying to work with.
Ideally components should only have to export derived types and not share shapes around.

Possible solution 1

Declare a Combine shape field type that combines an arbitrary derived object with a shape.
Implementation wise Combine<Derived, Shape> would derive Shape into Derived2 and then return Derived & Derived2.

// Child component
export type UserProp = Derive<User, { ... }>;

// Parent component
type BookProp = Shape<Book, {
    id: Auto;
    ...
    author: Combine<UserProp, {
        id: Auto; // optional expansion
    }>;
}>

Issues

The problem with this solution is that it's unclear what would happen when combining something like:

type UserProp = Derive<User, { name: Auto; }>;
type BookProp = {
    author: Combine<UserProp, { name: Alias<User, 'fullName', Auto>; }>;
};

As you can see the two name properties for User might get resolved to two completely different types.

To be fair with the current solution you'd get never which is also not ideal.

We are not exactly type safe

We are too flexible in that we don't warn against weird states like:

type User  = { id: number }
type SomeShape = Shape<User, {
    id: Auto;
    extra: Auto;
}>;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.