Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Purpose and safety of Any/Compute #156

Closed
michalczaplinski opened this issue Nov 6, 2020 · 1 comment
Closed

Purpose and safety of Any/Compute #156

michalczaplinski opened this issue Nov 6, 2020 · 1 comment
Assignees
Labels
enhancement Improving something question More info is requested
Projects

Comments

@michalczaplinski
Copy link

I'm looking at the Any/Compute type and my most immediate reaction is: "It seems super useful, so probably TS has a good reason not to compute the final type by default".

However, I think that I lack the deep TS expertise to know why that's the case. With that in mind:

  • Is Any/Compute safe to use for every type? Are there known edge cases?
  • Is it known why TypeScript chooses not to compute the final type by default? Is that just for efficiency?

Thanks for a great library! 🙂

@millsp millsp self-assigned this Nov 6, 2020
@millsp millsp added the question More info is requested label Nov 6, 2020
@millsp
Copy link
Owner

millsp commented Nov 6, 2020

I assume that this is purely for efficiency yes, or so that we can abstract certain types away (that we don't want to show), or both at the same time.

It is completely safe, there is absolutely no type loss. However, there is a drawback at the moment:

type O = {
    a: 'a'
    o: O
} & {
    b: {
        o: O
    }
}

type ComputedO = Compute<O>

Will yield a type that, when you look at it, is filled with anys. It just looks like any. In fact the type information is well preserved:

type test0 = ComputedO['o']['o']['o']['a']

This happens only on circular references. Lucky for us, I'm going to roll out a version that is able to handle circular references - to have even more beautiful outputs. If you want, give it a shot:

import {M} from 'ts-toolbelt'

export type ComputeDeep<A extends any, Seen = never> =
    A extends object
    ? A extends M.BuiltInObject | Seen
      ? A
      : {
            [K in keyof A]: ComputeDeep<A[K], A | Seen>
        } & {}
    : A

type A = {
    a: string
    o: O
}

type O = {
    a: 'a'
    o: A
}

type ComputedO = ComputeDeep<O>

type test0 = ComputedO['o']['o']['o']['a']

The TypeScript team provide very generic tools to do many things with the type system, they give us the choice to build libraries - which is great. But this can make it hard to learn and his is what ts-toolbelt tries to solve.

Thanks for a great library!

Thanks! If you have any question, I'm always here to help!

@millsp millsp closed this as completed Nov 6, 2020
@millsp millsp reopened this Nov 9, 2020
@millsp millsp added the enhancement Improving something label Nov 9, 2020
@stale stale bot added the wontfix This will not be worked on label Jan 9, 2021
@millsp millsp removed the wontfix This will not be worked on label Jan 9, 2021
Repository owner deleted a comment from stale bot Jan 12, 2021
@millsp millsp added this to To do in Board via automation Feb 1, 2021
@millsp millsp moved this from To do to In progress in Board Feb 1, 2021
@millsp millsp moved this from In progress to Done in Board Feb 1, 2021
@millsp millsp closed this as completed Feb 2, 2021
Repository owner locked and limited conversation to collaborators Feb 2, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
enhancement Improving something question More info is requested
Projects
Board
  
Done
Development

No branches or pull requests

2 participants