robsontenorio/vue-api-query

[RFC] Typescript Implementation

Closed this issue · 1 comments

Feature Name: Typescript Rewrite

Feature Branch: feat/typescript

Type: Feature

Start Date: 2020-10-23

End Date: 2020-11-06

Author: João Pedro Antunes Silva

Motivation: Typescript support have been requested.

Description

Documentation for Typescript configuration will be added

The package was rewritten using Typescript, with full types support and conditional types for responses. There are no breaking changes.

One of my goals when doing this rewrite was to have a precise type checking for responses.
As some responses might be wrapped in "data", I made the Model class a
Generic Class, which accepts two boolean arguments in order to conditionally change
the returned type from responses.

See Conditional Types for more information.

The first argument should be set to true if the collection is wrapped in "data".
The second argument should be set to true if the model is wrapped in "data".

For example, we can have a Post model that has a wrapped collection, but an unwrapped model:

import Model from './Model'

export default class Post extends Model<true, false> {/*...*/}

The backend response like this:

{
  data: [
    /* ... */
    {
      title: 'My awesome post',
      text: 'Some text here...'
    },
    {
      title: 'Another post',
      text: 'Some text here...'
    }
    /* ... */
  ]
}

Then we have the correct type checking:

const posts = new Post().get()

posts[0] // Error
posts.data[0] // Success

If all of your models follows the same structure, you can define the arguments in your Base model class, abstracting this configuration from your models.

import { Model as BaseModel } from 'vue-api-query'

export default class Model extends BaseModel <true, false> {/*...*/}

Note that I wasn't able to make precise type checkings for Static methods due to a limitation on Generic Classes:

Static members cannot reference class type parameters.

See Type Parameters in Static Members for more information.