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

Different behavior between inline type and type alias #29677

Closed
ozum opened this issue Feb 1, 2019 · 4 comments
Closed

Different behavior between inline type and type alias #29677

ozum opened this issue Feb 1, 2019 · 4 comments
Assignees
Labels
Bug A bug in TypeScript Domain: Conditional Types The issue relates to conditional types Fixed A PR has been merged for this issue

Comments

@ozum
Copy link

ozum commented Feb 1, 2019

TypeScript Version: 3.4.0-dev.20190131

I'm trying to find base types of some class properties. For example, for a given X[], trying to find X.

I use same definition inline and as a type alias. Type alias has error whereas inline type works.

Search Terms: Type alias, different behavior, conditional

Code

Below is simplified version of the actual code. Generics A1 and A2 in class method whereRelated are equal, except A1 uses inline type and A2 uses a type alias.

interface RelationFields {
  x: A;
  y: A[];
  z: A[];
}
type Name = keyof RelationFields;
type ShouldA<RF extends RelationFields, N extends Name> = RF[N] extends A[] ? RF[N][0] : never;

class A {
  x: A;
  y: A[];
  z: A[];

  whereRelated<
    RF extends RelationFields = RelationFields,
    N extends Name = Name,
    A1 extends A = RF[N] extends A[] ? RF[N][0] : never, // Works
    A2 extends A = ShouldA<RF, N> // Type is same as A1, but is not assignable to type A
  >(): number {
    return 1;
  }
}

Expected behavior:

Either both A1 and A2 work or both have errors.

Actual behavior:

A1 works, but A2 has an error: ... Type 'RelationFields[N][0]' is not assignable to type 'A'.

Playground Link: See here

Related Issues: #15973 seems similar, but I can not be sure. If this is an expected behavior, an advise how to use a type alias is appreciated.

Thanks,

@AnyhowStep
Copy link
Contributor

AnyhowStep commented Feb 1, 2019

I've run into similar problems before. Not quite your exact situation, though.

My hack-y workaround is to add a comment saying I'm about to use a workaround, and then do,

//For some reason, I need to surround this with Extract<>
//TODO Investigate
A2 extends A = Extract<ShouldA<RF, N>, A>

This is unrelated but is there a reason you use RF[N][0] instead of RF[N][number]?

@ozum
Copy link
Author

ozum commented Feb 1, 2019

@AnyhowStep Thanks for the tip for Extract. I will wrap original alias with Extract until finding a direct solution:

type ShouldA<RF extends RelationFields, N extends Name> = Extract<RF[N] extends A[] ? RF[N][0] : never, A>;

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Feb 1, 2019
@jack-williams
Copy link
Collaborator

I'm wondering if #29698 is also fundamentally related to this---inlining Record produces the correct errors.

@weswigham
Copy link
Member

@jack-williams nope.

@weswigham weswigham added Bug A bug in TypeScript Fixed A PR has been merged for this issue Domain: Conditional Types The issue relates to conditional types and removed Needs Investigation This issue needs a team member to investigate its status. labels Feb 22, 2019
@weswigham weswigham added this to the TypeScript 3.4.0 milestone Feb 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Domain: Conditional Types The issue relates to conditional types Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests

5 participants