mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Report generic rest parameters as unreliable variance positions (#33020)
* Report generic rest parameters as unreliable variance positions * Add example from discussion on #30301
This commit is contained in:
parent
5e0fbc677a
commit
7b02c635b6
@ -13919,7 +13919,7 @@ namespace ts {
|
||||
target: Signature,
|
||||
ignoreReturnTypes: boolean): boolean {
|
||||
return compareSignaturesRelated(source, target, CallbackCheck.None, ignoreReturnTypes, /*reportErrors*/ false,
|
||||
/*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
|
||||
/*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== Ternary.False;
|
||||
}
|
||||
|
||||
type ErrorReporter = (message: DiagnosticMessage, arg0?: string, arg1?: string) => void;
|
||||
@ -13943,7 +13943,8 @@ namespace ts {
|
||||
reportErrors: boolean,
|
||||
errorReporter: ErrorReporter | undefined,
|
||||
incompatibleErrorReporter: ((source: Type, target: Type) => void) | undefined,
|
||||
compareTypes: TypeComparer): Ternary {
|
||||
compareTypes: TypeComparer,
|
||||
reportUnreliableMarkers: TypeMapper | undefined): Ternary {
|
||||
// TODO (drosen): De-duplicate code between related functions.
|
||||
if (source === target) {
|
||||
return Ternary.True;
|
||||
@ -13966,6 +13967,9 @@ namespace ts {
|
||||
const sourceCount = getParameterCount(source);
|
||||
const sourceRestType = getNonArrayRestType(source);
|
||||
const targetRestType = getNonArrayRestType(target);
|
||||
if (sourceRestType || targetRestType) {
|
||||
void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers);
|
||||
}
|
||||
if (sourceRestType && targetRestType && sourceCount !== targetCount) {
|
||||
// We're not able to relate misaligned complex rest parameters
|
||||
return Ternary.False;
|
||||
@ -14013,7 +14017,7 @@ namespace ts {
|
||||
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
|
||||
const related = callbacks ?
|
||||
// TODO: GH#18217 It will work if they're both `undefined`, but not if only one is
|
||||
compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, incompatibleErrorReporter, compareTypes) :
|
||||
compareSignaturesRelated(targetSig!, sourceSig!, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) :
|
||||
!callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
|
||||
if (!related) {
|
||||
if (reportErrors) {
|
||||
@ -15967,7 +15971,7 @@ namespace ts {
|
||||
*/
|
||||
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: Type, target: Type) => void): Ternary {
|
||||
return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
|
||||
CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, incompatibleReporter, isRelatedTo);
|
||||
CallbackCheck.None, /*ignoreReturnTypes*/ false, reportErrors, reportError, incompatibleReporter, isRelatedTo, reportUnreliableMarkers);
|
||||
}
|
||||
|
||||
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
//// [aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts]
|
||||
// the type printback for every `test` below should be "y"
|
||||
|
||||
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
|
||||
type a = ExtendedMapper<any, any, [any]>;
|
||||
type b = ExtendedMapper<any, any, any[]>;
|
||||
type test = a extends b ? "y" : "n"
|
||||
let check: test = "y";
|
||||
|
||||
|
||||
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
|
||||
);
|
||||
|
||||
type a1 = ExtendedMapper1<any, any, [any]>;
|
||||
type b1 = ExtendedMapper1<any, any, any[]>;
|
||||
type test1 = a1 extends b1 ? "y" : "n"
|
||||
let check1: test1 = "y";
|
||||
|
||||
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
|
||||
);
|
||||
|
||||
type a2 = ExtendedMapper2<any, any, [any]>;
|
||||
type b2 = ExtendedMapper2<any, any, any[]>;
|
||||
type test2 = a2 extends b2 ? "y" : "n"
|
||||
let check2: test2 = "y";
|
||||
|
||||
type a3 = (name: string, mixed: any, args_0: any) => any
|
||||
type b3 = (name: string, mixed: any, ...args: any[]) => any
|
||||
|
||||
type test3 = a3 extends b3 ? "y" : "n"
|
||||
let check3: test3 = "y";
|
||||
|
||||
|
||||
//// [aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.js]
|
||||
"use strict";
|
||||
// the type printback for every `test` below should be "y"
|
||||
var check = "y";
|
||||
var check1 = "y";
|
||||
var check2 = "y";
|
||||
var check3 = "y";
|
||||
@ -0,0 +1,121 @@
|
||||
=== tests/cases/compiler/aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts ===
|
||||
// the type printback for every `test` below should be "y"
|
||||
|
||||
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
|
||||
>ExtendedMapper : Symbol(ExtendedMapper, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 0, 0))
|
||||
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 20))
|
||||
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 34))
|
||||
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 43))
|
||||
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 68))
|
||||
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 82))
|
||||
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 20))
|
||||
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 105))
|
||||
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 43))
|
||||
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 34))
|
||||
|
||||
type a = ExtendedMapper<any, any, [any]>;
|
||||
>a : Symbol(a, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 134))
|
||||
>ExtendedMapper : Symbol(ExtendedMapper, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 0, 0))
|
||||
|
||||
type b = ExtendedMapper<any, any, any[]>;
|
||||
>b : Symbol(b, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 3, 41))
|
||||
>ExtendedMapper : Symbol(ExtendedMapper, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 0, 0))
|
||||
|
||||
type test = a extends b ? "y" : "n"
|
||||
>test : Symbol(test, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 4, 41))
|
||||
>a : Symbol(a, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 2, 134))
|
||||
>b : Symbol(b, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 3, 41))
|
||||
|
||||
let check: test = "y";
|
||||
>check : Symbol(check, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 3))
|
||||
>test : Symbol(test, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 4, 41))
|
||||
|
||||
|
||||
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
>ExtendedMapper1 : Symbol(ExtendedMapper1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 22))
|
||||
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 21))
|
||||
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 35))
|
||||
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 44))
|
||||
|
||||
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
|
||||
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 10, 5))
|
||||
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 10, 19))
|
||||
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 21))
|
||||
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 10, 42))
|
||||
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 44))
|
||||
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 9, 35))
|
||||
|
||||
);
|
||||
|
||||
type a1 = ExtendedMapper1<any, any, [any]>;
|
||||
>a1 : Symbol(a1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 11, 2))
|
||||
>ExtendedMapper1 : Symbol(ExtendedMapper1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 22))
|
||||
|
||||
type b1 = ExtendedMapper1<any, any, any[]>;
|
||||
>b1 : Symbol(b1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 13, 43))
|
||||
>ExtendedMapper1 : Symbol(ExtendedMapper1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 6, 22))
|
||||
|
||||
type test1 = a1 extends b1 ? "y" : "n"
|
||||
>test1 : Symbol(test1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 14, 43))
|
||||
>a1 : Symbol(a1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 11, 2))
|
||||
>b1 : Symbol(b1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 13, 43))
|
||||
|
||||
let check1: test1 = "y";
|
||||
>check1 : Symbol(check1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 3))
|
||||
>test1 : Symbol(test1, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 14, 43))
|
||||
|
||||
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
>ExtendedMapper2 : Symbol(ExtendedMapper2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 24))
|
||||
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 21))
|
||||
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 35))
|
||||
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 44))
|
||||
|
||||
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
|
||||
>x : Symbol(x, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 5))
|
||||
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 8))
|
||||
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 22))
|
||||
>HandledInputT : Symbol(HandledInputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 21))
|
||||
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 19, 45))
|
||||
>ArgsT : Symbol(ArgsT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 44))
|
||||
>OutputT : Symbol(OutputT, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 18, 35))
|
||||
|
||||
);
|
||||
|
||||
type a2 = ExtendedMapper2<any, any, [any]>;
|
||||
>a2 : Symbol(a2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 20, 2))
|
||||
>ExtendedMapper2 : Symbol(ExtendedMapper2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 24))
|
||||
|
||||
type b2 = ExtendedMapper2<any, any, any[]>;
|
||||
>b2 : Symbol(b2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 22, 43))
|
||||
>ExtendedMapper2 : Symbol(ExtendedMapper2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 16, 24))
|
||||
|
||||
type test2 = a2 extends b2 ? "y" : "n"
|
||||
>test2 : Symbol(test2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 23, 43))
|
||||
>a2 : Symbol(a2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 20, 2))
|
||||
>b2 : Symbol(b2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 22, 43))
|
||||
|
||||
let check2: test2 = "y";
|
||||
>check2 : Symbol(check2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 25, 3))
|
||||
>test2 : Symbol(test2, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 23, 43))
|
||||
|
||||
type a3 = (name: string, mixed: any, args_0: any) => any
|
||||
>a3 : Symbol(a3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 25, 24))
|
||||
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 11))
|
||||
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 24))
|
||||
>args_0 : Symbol(args_0, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 36))
|
||||
|
||||
type b3 = (name: string, mixed: any, ...args: any[]) => any
|
||||
>b3 : Symbol(b3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 56))
|
||||
>name : Symbol(name, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 11))
|
||||
>mixed : Symbol(mixed, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 24))
|
||||
>args : Symbol(args, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 36))
|
||||
|
||||
type test3 = a3 extends b3 ? "y" : "n"
|
||||
>test3 : Symbol(test3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 59))
|
||||
>a3 : Symbol(a3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 25, 24))
|
||||
>b3 : Symbol(b3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 27, 56))
|
||||
|
||||
let check3: test3 = "y";
|
||||
>check3 : Symbol(check3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 31, 3))
|
||||
>test3 : Symbol(test3, Decl(aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts, 28, 59))
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
=== tests/cases/compiler/aliasOfGenericFunctionWithRestBehavedSameAsUnaliased.ts ===
|
||||
// the type printback for every `test` below should be "y"
|
||||
|
||||
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
|
||||
>ExtendedMapper : ExtendedMapper<HandledInputT, OutputT, ArgsT>
|
||||
>name : string
|
||||
>mixed : HandledInputT
|
||||
>args : ArgsT
|
||||
|
||||
type a = ExtendedMapper<any, any, [any]>;
|
||||
>a : ExtendedMapper<any, any, [any]>
|
||||
|
||||
type b = ExtendedMapper<any, any, any[]>;
|
||||
>b : ExtendedMapper<any, any, any[]>
|
||||
|
||||
type test = a extends b ? "y" : "n"
|
||||
>test : "y"
|
||||
|
||||
let check: test = "y";
|
||||
>check : "y"
|
||||
>"y" : "y"
|
||||
|
||||
|
||||
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
>ExtendedMapper1 : ExtendedMapper1<HandledInputT, OutputT, ArgsT>
|
||||
|
||||
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
|
||||
>name : string
|
||||
>mixed : HandledInputT
|
||||
>args : ArgsT
|
||||
|
||||
);
|
||||
|
||||
type a1 = ExtendedMapper1<any, any, [any]>;
|
||||
>a1 : ExtendedMapper1<any, any, [any]>
|
||||
|
||||
type b1 = ExtendedMapper1<any, any, any[]>;
|
||||
>b1 : ExtendedMapper1<any, any, any[]>
|
||||
|
||||
type test1 = a1 extends b1 ? "y" : "n"
|
||||
>test1 : "y"
|
||||
|
||||
let check1: test1 = "y";
|
||||
>check1 : "y"
|
||||
>"y" : "y"
|
||||
|
||||
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
>ExtendedMapper2 : (name: string, mixed: HandledInputT, ...args: ArgsT) => OutputT
|
||||
|
||||
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
|
||||
>x : (name: string, mixed: HandledInputT, ...args: ArgsT) => OutputT
|
||||
>name : string
|
||||
>mixed : HandledInputT
|
||||
>args : ArgsT
|
||||
|
||||
);
|
||||
|
||||
type a2 = ExtendedMapper2<any, any, [any]>;
|
||||
>a2 : (name: string, mixed: any, args_0: any) => any
|
||||
|
||||
type b2 = ExtendedMapper2<any, any, any[]>;
|
||||
>b2 : (name: string, mixed: any, ...args: any[]) => any
|
||||
|
||||
type test2 = a2 extends b2 ? "y" : "n"
|
||||
>test2 : "y"
|
||||
|
||||
let check2: test2 = "y";
|
||||
>check2 : "y"
|
||||
>"y" : "y"
|
||||
|
||||
type a3 = (name: string, mixed: any, args_0: any) => any
|
||||
>a3 : a3
|
||||
>name : string
|
||||
>mixed : any
|
||||
>args_0 : any
|
||||
|
||||
type b3 = (name: string, mixed: any, ...args: any[]) => any
|
||||
>b3 : b3
|
||||
>name : string
|
||||
>mixed : any
|
||||
>args : any[]
|
||||
|
||||
type test3 = a3 extends b3 ? "y" : "n"
|
||||
>test3 : "y"
|
||||
|
||||
let check3: test3 = "y";
|
||||
>check3 : "y"
|
||||
>"y" : "y"
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
//// [lambdaParameterWithTupleArgsHasCorrectAssignability.ts]
|
||||
type MyTupleItem = {};
|
||||
type MyTuple = [MyTupleItem, ...MyTupleItem[]];
|
||||
|
||||
type GenericFunction<T extends MyTuple> = (...fromArgs: T) => void;
|
||||
|
||||
class GenericClass<T extends MyTuple> {
|
||||
from: GenericFunction<T> | undefined;
|
||||
}
|
||||
|
||||
function createClass<T extends MyTuple>(f: GenericFunction<T>): GenericClass<T> {
|
||||
return new GenericClass<T>(/* ... use f */);
|
||||
}
|
||||
|
||||
function consumeClass(c: GenericClass<[string, boolean]>) { }
|
||||
|
||||
// should work
|
||||
consumeClass(createClass(str => console.log(str.length)));
|
||||
|
||||
// should work
|
||||
consumeClass(createClass((str, _unused_num) => console.log(str.length)));
|
||||
|
||||
|
||||
//// [lambdaParameterWithTupleArgsHasCorrectAssignability.js]
|
||||
"use strict";
|
||||
var GenericClass = /** @class */ (function () {
|
||||
function GenericClass() {
|
||||
}
|
||||
return GenericClass;
|
||||
}());
|
||||
function createClass(f) {
|
||||
return new GenericClass( /* ... use f */);
|
||||
}
|
||||
function consumeClass(c) { }
|
||||
// should work
|
||||
consumeClass(createClass(function (str) { return console.log(str.length); }));
|
||||
// should work
|
||||
consumeClass(createClass(function (str, _unused_num) { return console.log(str.length); }));
|
||||
@ -0,0 +1,72 @@
|
||||
=== tests/cases/compiler/lambdaParameterWithTupleArgsHasCorrectAssignability.ts ===
|
||||
type MyTupleItem = {};
|
||||
>MyTupleItem : Symbol(MyTupleItem, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 0, 0))
|
||||
|
||||
type MyTuple = [MyTupleItem, ...MyTupleItem[]];
|
||||
>MyTuple : Symbol(MyTuple, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 0, 22))
|
||||
>MyTupleItem : Symbol(MyTupleItem, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 0, 0))
|
||||
>MyTupleItem : Symbol(MyTupleItem, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 0, 0))
|
||||
|
||||
type GenericFunction<T extends MyTuple> = (...fromArgs: T) => void;
|
||||
>GenericFunction : Symbol(GenericFunction, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 1, 47))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 3, 21))
|
||||
>MyTuple : Symbol(MyTuple, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 0, 22))
|
||||
>fromArgs : Symbol(fromArgs, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 3, 43))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 3, 21))
|
||||
|
||||
class GenericClass<T extends MyTuple> {
|
||||
>GenericClass : Symbol(GenericClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 3, 67))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 5, 19))
|
||||
>MyTuple : Symbol(MyTuple, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 0, 22))
|
||||
|
||||
from: GenericFunction<T> | undefined;
|
||||
>from : Symbol(GenericClass.from, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 5, 39))
|
||||
>GenericFunction : Symbol(GenericFunction, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 1, 47))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 5, 19))
|
||||
}
|
||||
|
||||
function createClass<T extends MyTuple>(f: GenericFunction<T>): GenericClass<T> {
|
||||
>createClass : Symbol(createClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 7, 1))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 9, 21))
|
||||
>MyTuple : Symbol(MyTuple, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 0, 22))
|
||||
>f : Symbol(f, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 9, 40))
|
||||
>GenericFunction : Symbol(GenericFunction, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 1, 47))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 9, 21))
|
||||
>GenericClass : Symbol(GenericClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 3, 67))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 9, 21))
|
||||
|
||||
return new GenericClass<T>(/* ... use f */);
|
||||
>GenericClass : Symbol(GenericClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 3, 67))
|
||||
>T : Symbol(T, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 9, 21))
|
||||
}
|
||||
|
||||
function consumeClass(c: GenericClass<[string, boolean]>) { }
|
||||
>consumeClass : Symbol(consumeClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 11, 1))
|
||||
>c : Symbol(c, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 13, 22))
|
||||
>GenericClass : Symbol(GenericClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 3, 67))
|
||||
|
||||
// should work
|
||||
consumeClass(createClass(str => console.log(str.length)));
|
||||
>consumeClass : Symbol(consumeClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 11, 1))
|
||||
>createClass : Symbol(createClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 7, 1))
|
||||
>str : Symbol(str, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 16, 25))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>str.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>str : Symbol(str, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 16, 25))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
// should work
|
||||
consumeClass(createClass((str, _unused_num) => console.log(str.length)));
|
||||
>consumeClass : Symbol(consumeClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 11, 1))
|
||||
>createClass : Symbol(createClass, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 7, 1))
|
||||
>str : Symbol(str, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 19, 26))
|
||||
>_unused_num : Symbol(_unused_num, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 19, 30))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>str.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>str : Symbol(str, Decl(lambdaParameterWithTupleArgsHasCorrectAssignability.ts, 19, 26))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
=== tests/cases/compiler/lambdaParameterWithTupleArgsHasCorrectAssignability.ts ===
|
||||
type MyTupleItem = {};
|
||||
>MyTupleItem : MyTupleItem
|
||||
|
||||
type MyTuple = [MyTupleItem, ...MyTupleItem[]];
|
||||
>MyTuple : MyTuple
|
||||
|
||||
type GenericFunction<T extends MyTuple> = (...fromArgs: T) => void;
|
||||
>GenericFunction : GenericFunction<T>
|
||||
>fromArgs : T
|
||||
|
||||
class GenericClass<T extends MyTuple> {
|
||||
>GenericClass : GenericClass<T>
|
||||
|
||||
from: GenericFunction<T> | undefined;
|
||||
>from : GenericFunction<T> | undefined
|
||||
}
|
||||
|
||||
function createClass<T extends MyTuple>(f: GenericFunction<T>): GenericClass<T> {
|
||||
>createClass : <T extends MyTuple>(f: GenericFunction<T>) => GenericClass<T>
|
||||
>f : GenericFunction<T>
|
||||
|
||||
return new GenericClass<T>(/* ... use f */);
|
||||
>new GenericClass<T>(/* ... use f */) : GenericClass<T>
|
||||
>GenericClass : typeof GenericClass
|
||||
}
|
||||
|
||||
function consumeClass(c: GenericClass<[string, boolean]>) { }
|
||||
>consumeClass : (c: GenericClass<[string, boolean]>) => void
|
||||
>c : GenericClass<[string, boolean]>
|
||||
|
||||
// should work
|
||||
consumeClass(createClass(str => console.log(str.length)));
|
||||
>consumeClass(createClass(str => console.log(str.length))) : void
|
||||
>consumeClass : (c: GenericClass<[string, boolean]>) => void
|
||||
>createClass(str => console.log(str.length)) : GenericClass<[string]>
|
||||
>createClass : <T extends MyTuple>(f: GenericFunction<T>) => GenericClass<T>
|
||||
>str => console.log(str.length) : (str: string) => void
|
||||
>str : string
|
||||
>console.log(str.length) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>str.length : number
|
||||
>str : string
|
||||
>length : number
|
||||
|
||||
// should work
|
||||
consumeClass(createClass((str, _unused_num) => console.log(str.length)));
|
||||
>consumeClass(createClass((str, _unused_num) => console.log(str.length))) : void
|
||||
>consumeClass : (c: GenericClass<[string, boolean]>) => void
|
||||
>createClass((str, _unused_num) => console.log(str.length)) : GenericClass<[string, boolean]>
|
||||
>createClass : <T extends MyTuple>(f: GenericFunction<T>) => GenericClass<T>
|
||||
>(str, _unused_num) => console.log(str.length) : (str: string, _unused_num: boolean) => void
|
||||
>str : string
|
||||
>_unused_num : boolean
|
||||
>console.log(str.length) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>str.length : number
|
||||
>str : string
|
||||
>length : number
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
// @strict: true
|
||||
// the type printback for every `test` below should be "y"
|
||||
|
||||
type ExtendedMapper<HandledInputT, OutputT, ArgsT extends any[]> = (name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT;
|
||||
type a = ExtendedMapper<any, any, [any]>;
|
||||
type b = ExtendedMapper<any, any, any[]>;
|
||||
type test = a extends b ? "y" : "n"
|
||||
let check: test = "y";
|
||||
|
||||
|
||||
type ExtendedMapper1<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT
|
||||
);
|
||||
|
||||
type a1 = ExtendedMapper1<any, any, [any]>;
|
||||
type b1 = ExtendedMapper1<any, any, any[]>;
|
||||
type test1 = a1 extends b1 ? "y" : "n"
|
||||
let check1: test1 = "y";
|
||||
|
||||
type ExtendedMapper2<HandledInputT, OutputT, ArgsT extends any[]> = (
|
||||
{x:(name : string, mixed : HandledInputT, ...args : ArgsT) => OutputT}["x"]
|
||||
);
|
||||
|
||||
type a2 = ExtendedMapper2<any, any, [any]>;
|
||||
type b2 = ExtendedMapper2<any, any, any[]>;
|
||||
type test2 = a2 extends b2 ? "y" : "n"
|
||||
let check2: test2 = "y";
|
||||
|
||||
type a3 = (name: string, mixed: any, args_0: any) => any
|
||||
type b3 = (name: string, mixed: any, ...args: any[]) => any
|
||||
|
||||
type test3 = a3 extends b3 ? "y" : "n"
|
||||
let check3: test3 = "y";
|
||||
@ -0,0 +1,21 @@
|
||||
// @strict: true
|
||||
type MyTupleItem = {};
|
||||
type MyTuple = [MyTupleItem, ...MyTupleItem[]];
|
||||
|
||||
type GenericFunction<T extends MyTuple> = (...fromArgs: T) => void;
|
||||
|
||||
class GenericClass<T extends MyTuple> {
|
||||
from: GenericFunction<T> | undefined;
|
||||
}
|
||||
|
||||
function createClass<T extends MyTuple>(f: GenericFunction<T>): GenericClass<T> {
|
||||
return new GenericClass<T>(/* ... use f */);
|
||||
}
|
||||
|
||||
function consumeClass(c: GenericClass<[string, boolean]>) { }
|
||||
|
||||
// should work
|
||||
consumeClass(createClass(str => console.log(str.length)));
|
||||
|
||||
// should work
|
||||
consumeClass(createClass((str, _unused_num) => console.log(str.length)));
|
||||
Loading…
x
Reference in New Issue
Block a user