mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Remove bug-causing carve-out in conditional type instantiation that hopefully is no longer required (#51151)
This commit is contained in:
parent
37317a208f
commit
bdcc240d68
@ -16372,11 +16372,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
// We skip inference of the possible `infer` types unles the `extendsType` _is_ an infer type
|
||||
// if it was, it's trivial to say that extendsType = checkType, however such a pattern is used to
|
||||
// "reset" the type being build up during constraint calculation and avoid making an apparently "infinite" constraint
|
||||
// so in those cases we refain from performing inference and retain the uninfered type parameter
|
||||
if (!checkTypeInstantiable || !some(root.inferTypeParameters, t => t === extendsType)) {
|
||||
if (!checkTypeInstantiable) {
|
||||
// We don't want inferences from constraints as they may cause us to eagerly resolve the
|
||||
// conditional type instead of deferring resolution. Also, we always want strict function
|
||||
// types rules (i.e. proper contravariance) for inferences.
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
//// [recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts]
|
||||
export {}
|
||||
export interface Option<T> {
|
||||
zip1<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray1<O>]>;
|
||||
|
||||
zip2<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray2<O>]>;
|
||||
|
||||
zip3<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray3<O>]>;
|
||||
}
|
||||
|
||||
type UnzipOption<T> = T extends Option<infer V> ? V : never;
|
||||
|
||||
/// This doesn't work
|
||||
type UnzipOptionArray1<T> = { [k in keyof T]: T[k] extends Option<any> ? UnzipOption<T[k]> : never };
|
||||
|
||||
/// But these work
|
||||
type UnzipOptionArray2<T> = { [k in keyof T]: UnzipOption<T[k]> };
|
||||
type UnzipOptionArray3<T> = { [k in keyof T]: T[k] extends Option<infer V> ? V : never };
|
||||
|
||||
declare const opt1: Option<number>;
|
||||
declare const opt2: Option<string>;
|
||||
declare const opt3: Option<boolean>;
|
||||
|
||||
const zipped1 = opt1.zip1(opt2, opt3);
|
||||
const zipped2 = opt1.zip2(opt2, opt3);
|
||||
const zipped3 = opt1.zip3(opt2, opt3);
|
||||
|
||||
//// [recursiveTypeAliasWithSpreadConditionalReturnNotCircular.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var zipped1 = opt1.zip1(opt2, opt3);
|
||||
var zipped2 = opt1.zip2(opt2, opt3);
|
||||
var zipped3 = opt1.zip3(opt2, opt3);
|
||||
@ -0,0 +1,121 @@
|
||||
=== tests/cases/compiler/recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts ===
|
||||
export {}
|
||||
export interface Option<T> {
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 1, 24))
|
||||
|
||||
zip1<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray1<O>]>;
|
||||
>zip1 : Symbol(Option.zip1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 1, 28))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 2, 6))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>others : Symbol(others, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 2, 36))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 2, 6))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 1, 24))
|
||||
>UnzipOptionArray1 : Symbol(UnzipOptionArray1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 9, 60))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 2, 6))
|
||||
|
||||
zip2<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray2<O>]>;
|
||||
>zip2 : Symbol(Option.zip2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 2, 88))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 4, 6))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>others : Symbol(others, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 4, 36))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 4, 6))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 1, 24))
|
||||
>UnzipOptionArray2 : Symbol(UnzipOptionArray2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 101))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 4, 6))
|
||||
|
||||
zip3<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray3<O>]>;
|
||||
>zip3 : Symbol(Option.zip3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 4, 88))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 6, 6))
|
||||
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>others : Symbol(others, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 6, 36))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 6, 6))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 1, 24))
|
||||
>UnzipOptionArray3 : Symbol(UnzipOptionArray3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 15, 66))
|
||||
>O : Symbol(O, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 6, 6))
|
||||
}
|
||||
|
||||
type UnzipOption<T> = T extends Option<infer V> ? V : never;
|
||||
>UnzipOption : Symbol(UnzipOption, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 7, 1))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 9, 17))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 9, 17))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>V : Symbol(V, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 9, 44))
|
||||
>V : Symbol(V, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 9, 44))
|
||||
|
||||
/// This doesn't work
|
||||
type UnzipOptionArray1<T> = { [k in keyof T]: T[k] extends Option<any> ? UnzipOption<T[k]> : never };
|
||||
>UnzipOptionArray1 : Symbol(UnzipOptionArray1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 9, 60))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 23))
|
||||
>k : Symbol(k, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 31))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 23))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 23))
|
||||
>k : Symbol(k, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 31))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>UnzipOption : Symbol(UnzipOption, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 7, 1))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 23))
|
||||
>k : Symbol(k, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 31))
|
||||
|
||||
/// But these work
|
||||
type UnzipOptionArray2<T> = { [k in keyof T]: UnzipOption<T[k]> };
|
||||
>UnzipOptionArray2 : Symbol(UnzipOptionArray2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 12, 101))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 15, 23))
|
||||
>k : Symbol(k, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 15, 31))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 15, 23))
|
||||
>UnzipOption : Symbol(UnzipOption, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 7, 1))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 15, 23))
|
||||
>k : Symbol(k, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 15, 31))
|
||||
|
||||
type UnzipOptionArray3<T> = { [k in keyof T]: T[k] extends Option<infer V> ? V : never };
|
||||
>UnzipOptionArray3 : Symbol(UnzipOptionArray3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 15, 66))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 16, 23))
|
||||
>k : Symbol(k, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 16, 31))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 16, 23))
|
||||
>T : Symbol(T, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 16, 23))
|
||||
>k : Symbol(k, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 16, 31))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
>V : Symbol(V, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 16, 71))
|
||||
>V : Symbol(V, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 16, 71))
|
||||
|
||||
declare const opt1: Option<number>;
|
||||
>opt1 : Symbol(opt1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 18, 13))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
|
||||
declare const opt2: Option<string>;
|
||||
>opt2 : Symbol(opt2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 19, 13))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
|
||||
declare const opt3: Option<boolean>;
|
||||
>opt3 : Symbol(opt3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 20, 13))
|
||||
>Option : Symbol(Option, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 0, 9))
|
||||
|
||||
const zipped1 = opt1.zip1(opt2, opt3);
|
||||
>zipped1 : Symbol(zipped1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 22, 5))
|
||||
>opt1.zip1 : Symbol(Option.zip1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 1, 28))
|
||||
>opt1 : Symbol(opt1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 18, 13))
|
||||
>zip1 : Symbol(Option.zip1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 1, 28))
|
||||
>opt2 : Symbol(opt2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 19, 13))
|
||||
>opt3 : Symbol(opt3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 20, 13))
|
||||
|
||||
const zipped2 = opt1.zip2(opt2, opt3);
|
||||
>zipped2 : Symbol(zipped2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 23, 5))
|
||||
>opt1.zip2 : Symbol(Option.zip2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 2, 88))
|
||||
>opt1 : Symbol(opt1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 18, 13))
|
||||
>zip2 : Symbol(Option.zip2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 2, 88))
|
||||
>opt2 : Symbol(opt2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 19, 13))
|
||||
>opt3 : Symbol(opt3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 20, 13))
|
||||
|
||||
const zipped3 = opt1.zip3(opt2, opt3);
|
||||
>zipped3 : Symbol(zipped3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 24, 5))
|
||||
>opt1.zip3 : Symbol(Option.zip3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 4, 88))
|
||||
>opt1 : Symbol(opt1, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 18, 13))
|
||||
>zip3 : Symbol(Option.zip3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 4, 88))
|
||||
>opt2 : Symbol(opt2, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 19, 13))
|
||||
>opt3 : Symbol(opt3, Decl(recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts, 20, 13))
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
=== tests/cases/compiler/recursiveTypeAliasWithSpreadConditionalReturnNotCircular.ts ===
|
||||
export {}
|
||||
export interface Option<T> {
|
||||
zip1<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray1<O>]>;
|
||||
>zip1 : <O extends Option<any>[]>(...others: O) => Option<[T, ...UnzipOptionArray1<O>]>
|
||||
>others : O
|
||||
|
||||
zip2<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray2<O>]>;
|
||||
>zip2 : <O extends Option<any>[]>(...others: O) => Option<[T, ...UnzipOptionArray2<O>]>
|
||||
>others : O
|
||||
|
||||
zip3<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray3<O>]>;
|
||||
>zip3 : <O extends Option<any>[]>(...others: O) => Option<[T, ...UnzipOptionArray3<O>]>
|
||||
>others : O
|
||||
}
|
||||
|
||||
type UnzipOption<T> = T extends Option<infer V> ? V : never;
|
||||
>UnzipOption : UnzipOption<T>
|
||||
|
||||
/// This doesn't work
|
||||
type UnzipOptionArray1<T> = { [k in keyof T]: T[k] extends Option<any> ? UnzipOption<T[k]> : never };
|
||||
>UnzipOptionArray1 : UnzipOptionArray1<T>
|
||||
|
||||
/// But these work
|
||||
type UnzipOptionArray2<T> = { [k in keyof T]: UnzipOption<T[k]> };
|
||||
>UnzipOptionArray2 : UnzipOptionArray2<T>
|
||||
|
||||
type UnzipOptionArray3<T> = { [k in keyof T]: T[k] extends Option<infer V> ? V : never };
|
||||
>UnzipOptionArray3 : UnzipOptionArray3<T>
|
||||
|
||||
declare const opt1: Option<number>;
|
||||
>opt1 : Option<number>
|
||||
|
||||
declare const opt2: Option<string>;
|
||||
>opt2 : Option<string>
|
||||
|
||||
declare const opt3: Option<boolean>;
|
||||
>opt3 : Option<boolean>
|
||||
|
||||
const zipped1 = opt1.zip1(opt2, opt3);
|
||||
>zipped1 : Option<[number, string, boolean]>
|
||||
>opt1.zip1(opt2, opt3) : Option<[number, string, boolean]>
|
||||
>opt1.zip1 : <O extends Option<any>[]>(...others: O) => Option<[number, ...UnzipOptionArray1<O>]>
|
||||
>opt1 : Option<number>
|
||||
>zip1 : <O extends Option<any>[]>(...others: O) => Option<[number, ...UnzipOptionArray1<O>]>
|
||||
>opt2 : Option<string>
|
||||
>opt3 : Option<boolean>
|
||||
|
||||
const zipped2 = opt1.zip2(opt2, opt3);
|
||||
>zipped2 : Option<[number, string, boolean]>
|
||||
>opt1.zip2(opt2, opt3) : Option<[number, string, boolean]>
|
||||
>opt1.zip2 : <O extends Option<any>[]>(...others: O) => Option<[number, ...UnzipOptionArray2<O>]>
|
||||
>opt1 : Option<number>
|
||||
>zip2 : <O extends Option<any>[]>(...others: O) => Option<[number, ...UnzipOptionArray2<O>]>
|
||||
>opt2 : Option<string>
|
||||
>opt3 : Option<boolean>
|
||||
|
||||
const zipped3 = opt1.zip3(opt2, opt3);
|
||||
>zipped3 : Option<[number, string, boolean]>
|
||||
>opt1.zip3(opt2, opt3) : Option<[number, string, boolean]>
|
||||
>opt1.zip3 : <O extends Option<any>[]>(...others: O) => Option<[number, ...UnzipOptionArray3<O>]>
|
||||
>opt1 : Option<number>
|
||||
>zip3 : <O extends Option<any>[]>(...others: O) => Option<[number, ...UnzipOptionArray3<O>]>
|
||||
>opt2 : Option<string>
|
||||
>opt3 : Option<boolean>
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
export {}
|
||||
export interface Option<T> {
|
||||
zip1<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray1<O>]>;
|
||||
|
||||
zip2<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray2<O>]>;
|
||||
|
||||
zip3<O extends Array<Option<any>>>(...others: O): Option<[T, ...UnzipOptionArray3<O>]>;
|
||||
}
|
||||
|
||||
type UnzipOption<T> = T extends Option<infer V> ? V : never;
|
||||
|
||||
/// This doesn't work
|
||||
type UnzipOptionArray1<T> = { [k in keyof T]: T[k] extends Option<any> ? UnzipOption<T[k]> : never };
|
||||
|
||||
/// But these work
|
||||
type UnzipOptionArray2<T> = { [k in keyof T]: UnzipOption<T[k]> };
|
||||
type UnzipOptionArray3<T> = { [k in keyof T]: T[k] extends Option<infer V> ? V : never };
|
||||
|
||||
declare const opt1: Option<number>;
|
||||
declare const opt2: Option<string>;
|
||||
declare const opt3: Option<boolean>;
|
||||
|
||||
const zipped1 = opt1.zip1(opt2, opt3);
|
||||
const zipped2 = opt1.zip2(opt2, opt3);
|
||||
const zipped3 = opt1.zip3(opt2, opt3);
|
||||
Loading…
x
Reference in New Issue
Block a user