-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Closed
Labels
Needs More InfoThe issue still hasn't been fully clarifiedThe issue still hasn't been fully clarified
Description
Bug Report
Vue team is witnessing a new weird type behavior difference when upgrading TypeScript.
The typing difference is very subtle. I'm sorry I cannot provide a more concise example here. (The example has already been reduced from 500+ lines to 70 lines ).
The original usage is simple https://tsplay.dev/mxjRXw. I have attached the standalone example in the issue. All critical parts are commented.
🔎 Search Terms
Sorry I could not find a good search term.
🕗 Version & Regression Information
- This changed between versions 4.9.2 and 5.1.0dev
⏯ Playground Link
💻 Code
type ComponentPublicInstance<C, Options> = {
$options: Options & 'intersection anything' // intersection here is critical
} & ExtractComputedReturns<C> // this type intersection is important
type WhatEver<T> = T extends 1 ? true : false
type MixinToOptionTypes<T> = T extends ComponentOptionsBase<
infer C, 1, 1
>
? OptionTypesType<C>
: never
type IntersectionMixin<T> = WhatEver<T> extends true // a conditional is required here for reproduction
? OptionTypesType<{}>
: MixinToOptionTypes<T>
type CreateComponentPublicInstance<
Mixin extends 1 ,
Extends extends 1,
> = ComponentPublicInstance<
(IntersectionMixin<Mixin> & IntersectionMixin<Extends>)['C'],
ComponentOptionsBase<{}, Mixin, Extends>
>
interface ComponentOptionsBase<
_C extends ComputedOptions,
Mixin extends 1,
Extends extends 1,
> {
data?: (
this: CreateComponentPublicInstance<
Mixin,
Extends
>,
) => {} // a function property is required, method syntax cannot reproduce.
}
type ComputedGetter = (...args: any[]) => any
type ComputedOptions = Record<
string,
ComputedGetter | {get: ComputedGetter } // a union type for getter is required
>
type ExtractComputedReturns<T extends any> = {
[key in keyof T]: T[key] extends { get: (...args: any[]) => infer TReturn }
? TReturn
: T[key] extends (...args: any[]) => infer TReturn
? TReturn
: never
}
type OptionTypesType<C = {}> = { C: C }
type Mixin = 1; type Extend = 1;
type A1 = ComponentOptionsBase<any,Mixin,Extend> &{sth?:never}
export type Test1 = A1 extends ComponentOptionsBase<any,any,any>?'yes':'no'
// ^? expect Yes, got No in TS 5.1.0, but Yes in 4.9.5
// following types are for reference. They behave the same.
type A2 = ComponentOptionsBase<any,Mixin,Extend>
export type Test2 = A2 extends ComponentOptionsBase<any,any,any>?'yes':'no'
// ^? yes
type A3 = ComponentOptionsBase<any,Mixin,any> &{sth?:never}
export type Test3 = A3 extends ComponentOptionsBase<any,any,any>?'yes':'no'
// ^? yes
type A4 = ComponentOptionsBase<any,any,Extend> &{sth?:never}
export type Test4 = A4 extends ComponentOptionsBase<any,any,any>?'yes':'no'
// ^? yes🙁 Actual behavior
A1 should always be 'yes' in TS 5.1.0.
🙂 Expected behavior
A1 is 'no' in TS5.1.0, but 'yes' in TS4.9.5
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Needs More InfoThe issue still hasn't been fully clarifiedThe issue still hasn't been fully clarified