Skip to content
This repository has been archived by the owner on Mar 20, 2022. It is now read-only.

Improve typescript typing #363

Merged
merged 2 commits into from
Mar 6, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,12 @@ export type Schema =
schema.Values[] |
{[key: string]: Schema | Schema[]};

export function normalize(
export type NormalizedSchema<E, R> = { entities: E, result: R };
Copy link
Contributor

Choose a reason for hiding this comment

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

You probably want entities to be something like { [key:string]: { [key:string]: E } } since it's guaranteed to be nested with string

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See this example, the entities are not the same

{
  result: "123",
  entities: {
    "articles": {
      "123": {
        id: "123",
        author: "1",
        title: "My awesome blog post",
        comments: [ "324" ]
      }
    },
    "users": {
      "1": { "id": "1", "name": "Paul" },
      "2": { "id": "2", "name": "Nicole" }
    },
    "comments": {
      "324": { id: "324", "commenter": "2" }
    }
  }
}

You prefer to type this, like this

type List<E> = {
  [key: string]: E
}

type Entities = {
  articles: List<Article>
  users: List<User>
  comments: List<Comment>
}

And then NormalizedSchema<Entities>

Copy link
Contributor

Choose a reason for hiding this comment

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

I can see how that would be more specific if you put the work in. For my cases I was happy with 'any' for the final result and really wanted to have the typings of the nesting level.

For me there's no way to know all the entity types statically, so this is unfeasible for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I let the default any value so you can use it like you do.

But this can't be use with the no-unsafe-any rule from tslint.

It's not about typescript checking the type of the entity. It about typescript checking the use of the entity after you normalized them.

cont normalized = normalize<Entities>(...);

const foo = normalized.articles // known as Article.
foo.author // no error
foo.name // error
const bar = normalized.user // error

With the less precise typing you ask, we will have

const foo = normalized.articles // known as Entity = Article | User | Comment
foo.author // error !!!
foo.name // error
const bar = normalized.user // no error !!!

Choose a reason for hiding this comment

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

this makes sense, the typing should be on the entity. also @ntucker you can opt out by using any.


export function normalize<E = any, R = any>(
data: any,
schema: Schema
): {
entities: any,
result: any
};
): NormalizedSchema<E, R>;

export function denormalize(
input: any,
Expand Down