mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge pull request #11673 from Microsoft/partiallyAnnotatedSignatures
Contextual typing of partially annotated signatures
This commit is contained in:
+47
-19
@@ -3144,8 +3144,7 @@ namespace ts {
|
||||
// Use contextual parameter type if one is available
|
||||
let type: Type;
|
||||
if (declaration.symbol.name === "this") {
|
||||
const thisParameter = getContextualThisParameter(func);
|
||||
type = thisParameter ? getTypeOfSymbol(thisParameter) : undefined;
|
||||
type = getContextualThisParameterType(func);
|
||||
}
|
||||
else {
|
||||
type = getContextuallyTypedParameterType(<ParameterDeclaration>declaration);
|
||||
@@ -4789,9 +4788,6 @@ namespace ts {
|
||||
if (isJSConstructSignature) {
|
||||
minArgumentCount--;
|
||||
}
|
||||
if (!thisParameter && isObjectLiteralMethod(declaration)) {
|
||||
thisParameter = getContextualThisParameter(declaration);
|
||||
}
|
||||
|
||||
const classType = declaration.kind === SyntaxKind.Constructor ?
|
||||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
||||
@@ -6101,9 +6097,24 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration) {
|
||||
const areAllParametersUntyped = !forEach(node.parameters, p => p.type);
|
||||
const isNullaryArrow = node.kind === SyntaxKind.ArrowFunction && !node.parameters.length;
|
||||
return !node.typeParameters && areAllParametersUntyped && !isNullaryArrow;
|
||||
// Functions with type parameters are not context sensitive.
|
||||
if (node.typeParameters) {
|
||||
return false;
|
||||
}
|
||||
// Functions with any parameters that lack type annotations are context sensitive.
|
||||
if (forEach(node.parameters, p => !p.type)) {
|
||||
return true;
|
||||
}
|
||||
// For arrow functions we now know we're not context sensitive.
|
||||
if (node.kind === SyntaxKind.ArrowFunction) {
|
||||
return false;
|
||||
}
|
||||
// If the first parameter is not an explicit 'this' parameter, then the function has
|
||||
// an implicit 'this' parameter which is subject to contextual typing. Otherwise we
|
||||
// know that all parameters (including 'this') have type annotations and nothing is
|
||||
// subject to contextual typing.
|
||||
const parameter = firstOrUndefined(node.parameters);
|
||||
return !(parameter && parameterIsThisKeyword(parameter));
|
||||
}
|
||||
|
||||
function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
|
||||
@@ -9629,7 +9640,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const thisType = getThisTypeOfDeclaration(container);
|
||||
const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
|
||||
if (thisType) {
|
||||
return thisType;
|
||||
}
|
||||
@@ -9869,14 +9880,16 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getContextualThisParameter(func: FunctionLikeDeclaration): Symbol {
|
||||
function getContextualThisParameterType(func: FunctionLikeDeclaration): Type {
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
return contextualSignature.thisParameter;
|
||||
const thisParameter = contextualSignature.thisParameter;
|
||||
if (thisParameter) {
|
||||
return getTypeOfSymbol(thisParameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -12843,21 +12856,36 @@ namespace ts {
|
||||
|
||||
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) {
|
||||
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
if (isInferentialContext(mapper)) {
|
||||
for (let i = 0; i < len; i++) {
|
||||
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
|
||||
if (declaration.type) {
|
||||
inferTypes(mapper.context, getTypeFromTypeNode(declaration.type), getTypeAtPosition(context, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (context.thisParameter) {
|
||||
if (!signature.thisParameter) {
|
||||
signature.thisParameter = createTransientSymbol(context.thisParameter, undefined);
|
||||
const parameter = signature.thisParameter;
|
||||
if (!parameter || parameter.valueDeclaration && !(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
if (!parameter) {
|
||||
signature.thisParameter = createTransientSymbol(context.thisParameter, undefined);
|
||||
}
|
||||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper);
|
||||
}
|
||||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper);
|
||||
}
|
||||
for (let i = 0; i < len; i++) {
|
||||
const parameter = signature.parameters[i];
|
||||
const contextualParameterType = getTypeAtPosition(context, i);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
const contextualParameterType = getTypeAtPosition(context, i);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
}
|
||||
}
|
||||
if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
|
||||
const parameter = lastOrUndefined(signature.parameters);
|
||||
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts(12,11): error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'.
|
||||
tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts(13,11): error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'.
|
||||
tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts(14,11): error TS2345: Argument of type '(t1: C, t2: C, t3: D) => void' is not assignable to parameter of type '(t: C, t1: C) => void'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceError.ts (3 errors) ====
|
||||
class C {
|
||||
test: string
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
test2: string
|
||||
}
|
||||
|
||||
declare function testError<T extends C>(a: (t: T, t1: T) => void): T
|
||||
|
||||
// more args
|
||||
testError((t1: D, t2, t3) => {})
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'.
|
||||
testError((t1, t2: D, t3) => {})
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(t1: D, t2: D, t3: any) => void' is not assignable to parameter of type '(t: D, t1: D) => void'.
|
||||
testError((t1, t2, t3: D) => {})
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(t1: C, t2: C, t3: D) => void' is not assignable to parameter of type '(t: C, t1: C) => void'.
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
//// [partiallyAnnotatedFunctionInferenceError.ts]
|
||||
class C {
|
||||
test: string
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
test2: string
|
||||
}
|
||||
|
||||
declare function testError<T extends C>(a: (t: T, t1: T) => void): T
|
||||
|
||||
// more args
|
||||
testError((t1: D, t2, t3) => {})
|
||||
testError((t1, t2: D, t3) => {})
|
||||
testError((t1, t2, t3: D) => {})
|
||||
|
||||
|
||||
//// [partiallyAnnotatedFunctionInferenceError.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
return _super.apply(this, arguments) || this;
|
||||
}
|
||||
return D;
|
||||
}(C));
|
||||
// more args
|
||||
testError(function (t1, t2, t3) { });
|
||||
testError(function (t1, t2, t3) { });
|
||||
testError(function (t1, t2, t3) { });
|
||||
@@ -0,0 +1,85 @@
|
||||
//// [partiallyAnnotatedFunctionInferenceWithTypeParameter.ts]
|
||||
class C {
|
||||
test: string
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
test2: string
|
||||
}
|
||||
|
||||
declare function test<T extends C>(a: (t: T, t1: T) => void): T
|
||||
|
||||
declare function testRest<T extends C>(a: (t: T, t1: T, ...ts: T[]) => void): T
|
||||
|
||||
|
||||
// exactly
|
||||
test((t1: D, t2) => { t2.test2 })
|
||||
test((t1, t2: D) => { t2.test2 })
|
||||
|
||||
// zero arg
|
||||
test(() => {})
|
||||
|
||||
// fewer args
|
||||
test((t1: D) => {})
|
||||
|
||||
// rest arg
|
||||
test((...ts: D[]) => {})
|
||||
|
||||
// source function has rest arg
|
||||
testRest((t1: D) => {})
|
||||
testRest((t1, t2, t3) => {})
|
||||
testRest((t1: D, t2, t3) => {})
|
||||
testRest((t1, t2: D, t3) => {})
|
||||
testRest((t2: D, ...t3) => {})
|
||||
testRest((t2, ...t3: D[]) => {})
|
||||
|
||||
|
||||
//// [partiallyAnnotatedFunctionInferenceWithTypeParameter.js]
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
var D = (function (_super) {
|
||||
__extends(D, _super);
|
||||
function D() {
|
||||
return _super.apply(this, arguments) || this;
|
||||
}
|
||||
return D;
|
||||
}(C));
|
||||
// exactly
|
||||
test(function (t1, t2) { t2.test2; });
|
||||
test(function (t1, t2) { t2.test2; });
|
||||
// zero arg
|
||||
test(function () { });
|
||||
// fewer args
|
||||
test(function (t1) { });
|
||||
// rest arg
|
||||
test(function () {
|
||||
var ts = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
ts[_i - 0] = arguments[_i];
|
||||
}
|
||||
});
|
||||
// source function has rest arg
|
||||
testRest(function (t1) { });
|
||||
testRest(function (t1, t2, t3) { });
|
||||
testRest(function (t1, t2, t3) { });
|
||||
testRest(function (t1, t2, t3) { });
|
||||
testRest(function (t2) {
|
||||
var t3 = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
t3[_i - 1] = arguments[_i];
|
||||
}
|
||||
});
|
||||
testRest(function (t2) {
|
||||
var t3 = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
t3[_i - 1] = arguments[_i];
|
||||
}
|
||||
});
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0))
|
||||
|
||||
test: string
|
||||
>test : Symbol(C.test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 9))
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0))
|
||||
|
||||
test2: string
|
||||
>test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19))
|
||||
}
|
||||
|
||||
declare function test<T extends C>(a: (t: T, t1: T) => void): T
|
||||
>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22))
|
||||
>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 35))
|
||||
>t : Symbol(t, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 39))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 44))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 22))
|
||||
|
||||
declare function testRest<T extends C>(a: (t: T, t1: T, ...ts: T[]) => void): T
|
||||
>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26))
|
||||
>C : Symbol(C, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 39))
|
||||
>t : Symbol(t, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 43))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 48))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26))
|
||||
>ts : Symbol(ts, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 55))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26))
|
||||
>T : Symbol(T, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 10, 26))
|
||||
|
||||
|
||||
// exactly
|
||||
test((t1: D, t2) => { t2.test2 })
|
||||
>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 14, 6))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 14, 12))
|
||||
>t2.test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 14, 12))
|
||||
>test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19))
|
||||
|
||||
test((t1, t2: D) => { t2.test2 })
|
||||
>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 15, 6))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 15, 9))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
>t2.test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 15, 9))
|
||||
>test2 : Symbol(D.test2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 4, 19))
|
||||
|
||||
// zero arg
|
||||
test(() => {})
|
||||
>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1))
|
||||
|
||||
// fewer args
|
||||
test((t1: D) => {})
|
||||
>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 21, 6))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
|
||||
// rest arg
|
||||
test((...ts: D[]) => {})
|
||||
>test : Symbol(test, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 6, 1))
|
||||
>ts : Symbol(ts, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 24, 6))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
|
||||
// source function has rest arg
|
||||
testRest((t1: D) => {})
|
||||
>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 27, 10))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
|
||||
testRest((t1, t2, t3) => {})
|
||||
>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 28, 10))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 28, 13))
|
||||
>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 28, 17))
|
||||
|
||||
testRest((t1: D, t2, t3) => {})
|
||||
>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 29, 10))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 29, 16))
|
||||
>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 29, 20))
|
||||
|
||||
testRest((t1, t2: D, t3) => {})
|
||||
>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63))
|
||||
>t1 : Symbol(t1, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 30, 10))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 30, 13))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 30, 20))
|
||||
|
||||
testRest((t2: D, ...t3) => {})
|
||||
>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 31, 10))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 31, 16))
|
||||
|
||||
testRest((t2, ...t3: D[]) => {})
|
||||
>testRest : Symbol(testRest, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 8, 63))
|
||||
>t2 : Symbol(t2, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 32, 10))
|
||||
>t3 : Symbol(t3, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 32, 13))
|
||||
>D : Symbol(D, Decl(partiallyAnnotatedFunctionInferenceWithTypeParameter.ts, 2, 1))
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionInferenceWithTypeParameter.ts ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
test: string
|
||||
>test : string
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
>D : D
|
||||
>C : C
|
||||
|
||||
test2: string
|
||||
>test2 : string
|
||||
}
|
||||
|
||||
declare function test<T extends C>(a: (t: T, t1: T) => void): T
|
||||
>test : <T extends C>(a: (t: T, t1: T) => void) => T
|
||||
>T : T
|
||||
>C : C
|
||||
>a : (t: T, t1: T) => void
|
||||
>t : T
|
||||
>T : T
|
||||
>t1 : T
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
declare function testRest<T extends C>(a: (t: T, t1: T, ...ts: T[]) => void): T
|
||||
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
|
||||
>T : T
|
||||
>C : C
|
||||
>a : (t: T, t1: T, ...ts: T[]) => void
|
||||
>t : T
|
||||
>T : T
|
||||
>t1 : T
|
||||
>T : T
|
||||
>ts : T[]
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
|
||||
// exactly
|
||||
test((t1: D, t2) => { t2.test2 })
|
||||
>test((t1: D, t2) => { t2.test2 }) : D
|
||||
>test : <T extends C>(a: (t: T, t1: T) => void) => T
|
||||
>(t1: D, t2) => { t2.test2 } : (t1: D, t2: D) => void
|
||||
>t1 : D
|
||||
>D : D
|
||||
>t2 : D
|
||||
>t2.test2 : string
|
||||
>t2 : D
|
||||
>test2 : string
|
||||
|
||||
test((t1, t2: D) => { t2.test2 })
|
||||
>test((t1, t2: D) => { t2.test2 }) : D
|
||||
>test : <T extends C>(a: (t: T, t1: T) => void) => T
|
||||
>(t1, t2: D) => { t2.test2 } : (t1: D, t2: D) => void
|
||||
>t1 : D
|
||||
>t2 : D
|
||||
>D : D
|
||||
>t2.test2 : string
|
||||
>t2 : D
|
||||
>test2 : string
|
||||
|
||||
// zero arg
|
||||
test(() => {})
|
||||
>test(() => {}) : C
|
||||
>test : <T extends C>(a: (t: T, t1: T) => void) => T
|
||||
>() => {} : () => void
|
||||
|
||||
// fewer args
|
||||
test((t1: D) => {})
|
||||
>test((t1: D) => {}) : D
|
||||
>test : <T extends C>(a: (t: T, t1: T) => void) => T
|
||||
>(t1: D) => {} : (t1: D) => void
|
||||
>t1 : D
|
||||
>D : D
|
||||
|
||||
// rest arg
|
||||
test((...ts: D[]) => {})
|
||||
>test((...ts: D[]) => {}) : D
|
||||
>test : <T extends C>(a: (t: T, t1: T) => void) => T
|
||||
>(...ts: D[]) => {} : (...ts: D[]) => void
|
||||
>ts : D[]
|
||||
>D : D
|
||||
|
||||
// source function has rest arg
|
||||
testRest((t1: D) => {})
|
||||
>testRest((t1: D) => {}) : D
|
||||
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
|
||||
>(t1: D) => {} : (t1: D) => void
|
||||
>t1 : D
|
||||
>D : D
|
||||
|
||||
testRest((t1, t2, t3) => {})
|
||||
>testRest((t1, t2, t3) => {}) : C
|
||||
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
|
||||
>(t1, t2, t3) => {} : (t1: C, t2: C, t3: C) => void
|
||||
>t1 : C
|
||||
>t2 : C
|
||||
>t3 : C
|
||||
|
||||
testRest((t1: D, t2, t3) => {})
|
||||
>testRest((t1: D, t2, t3) => {}) : D
|
||||
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
|
||||
>(t1: D, t2, t3) => {} : (t1: D, t2: D, t3: D) => void
|
||||
>t1 : D
|
||||
>D : D
|
||||
>t2 : D
|
||||
>t3 : D
|
||||
|
||||
testRest((t1, t2: D, t3) => {})
|
||||
>testRest((t1, t2: D, t3) => {}) : D
|
||||
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
|
||||
>(t1, t2: D, t3) => {} : (t1: D, t2: D, t3: D) => void
|
||||
>t1 : D
|
||||
>t2 : D
|
||||
>D : D
|
||||
>t3 : D
|
||||
|
||||
testRest((t2: D, ...t3) => {})
|
||||
>testRest((t2: D, ...t3) => {}) : any
|
||||
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
|
||||
>(t2: D, ...t3) => {} : (t2: D, ...t3: any[]) => void
|
||||
>t2 : D
|
||||
>D : D
|
||||
>t3 : any[]
|
||||
|
||||
testRest((t2, ...t3: D[]) => {})
|
||||
>testRest((t2, ...t3: D[]) => {}) : C
|
||||
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
|
||||
>(t2, ...t3: D[]) => {} : (t2: C, ...t3: D[]) => void
|
||||
>t2 : C
|
||||
>t3 : D[]
|
||||
>D : D
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
//// [partiallyAnnotatedFunctionWitoutTypeParameter.ts]
|
||||
|
||||
// simple case
|
||||
declare function simple(f: (a: number, b: number) => void): {}
|
||||
|
||||
simple((a: number, b) => {})
|
||||
simple((a, b: number) => {})
|
||||
|
||||
|
||||
//// [partiallyAnnotatedFunctionWitoutTypeParameter.js]
|
||||
simple(function (a, b) { });
|
||||
simple(function (a, b) { });
|
||||
@@ -0,0 +1,19 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts ===
|
||||
|
||||
// simple case
|
||||
declare function simple(f: (a: number, b: number) => void): {}
|
||||
>simple : Symbol(simple, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 0, 0))
|
||||
>f : Symbol(f, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 2, 24))
|
||||
>a : Symbol(a, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 2, 28))
|
||||
>b : Symbol(b, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 2, 38))
|
||||
|
||||
simple((a: number, b) => {})
|
||||
>simple : Symbol(simple, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 4, 8))
|
||||
>b : Symbol(b, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 4, 18))
|
||||
|
||||
simple((a, b: number) => {})
|
||||
>simple : Symbol(simple, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 5, 8))
|
||||
>b : Symbol(b, Decl(partiallyAnnotatedFunctionWitoutTypeParameter.ts, 5, 10))
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
=== tests/cases/conformance/types/contextualTypes/partiallyAnnotatedFunction/partiallyAnnotatedFunctionWitoutTypeParameter.ts ===
|
||||
|
||||
// simple case
|
||||
declare function simple(f: (a: number, b: number) => void): {}
|
||||
>simple : (f: (a: number, b: number) => void) => {}
|
||||
>f : (a: number, b: number) => void
|
||||
>a : number
|
||||
>b : number
|
||||
|
||||
simple((a: number, b) => {})
|
||||
>simple((a: number, b) => {}) : {}
|
||||
>simple : (f: (a: number, b: number) => void) => {}
|
||||
>(a: number, b) => {} : (a: number, b: number) => void
|
||||
>a : number
|
||||
>b : number
|
||||
|
||||
simple((a, b: number) => {})
|
||||
>simple((a, b: number) => {}) : {}
|
||||
>simple : (f: (a: number, b: number) => void) => {}
|
||||
>(a, b: number) => {} : (a: number, b: number) => void
|
||||
>a : number
|
||||
>b : number
|
||||
|
||||
@@ -453,7 +453,7 @@ let anyToSpecified: (this: { y: number }, x: number) => number = function(x: num
|
||||
>this : { y: number; }
|
||||
>y : number
|
||||
>x : number
|
||||
>function(x: number): number { return x + 12; } : (x: number) => number
|
||||
>function(x: number): number { return x + 12; } : (this: { y: number; }, x: number) => number
|
||||
>x : number
|
||||
>x + 12 : number
|
||||
>x : number
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class C {
|
||||
test: string
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
test2: string
|
||||
}
|
||||
|
||||
declare function testError<T extends C>(a: (t: T, t1: T) => void): T
|
||||
|
||||
// more args
|
||||
testError((t1: D, t2, t3) => {})
|
||||
testError((t1, t2: D, t3) => {})
|
||||
testError((t1, t2, t3: D) => {})
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
class C {
|
||||
test: string
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
test2: string
|
||||
}
|
||||
|
||||
declare function test<T extends C>(a: (t: T, t1: T) => void): T
|
||||
|
||||
declare function testRest<T extends C>(a: (t: T, t1: T, ...ts: T[]) => void): T
|
||||
|
||||
|
||||
// exactly
|
||||
test((t1: D, t2) => { t2.test2 })
|
||||
test((t1, t2: D) => { t2.test2 })
|
||||
|
||||
// zero arg
|
||||
test(() => {})
|
||||
|
||||
// fewer args
|
||||
test((t1: D) => {})
|
||||
|
||||
// rest arg
|
||||
test((...ts: D[]) => {})
|
||||
|
||||
// source function has rest arg
|
||||
testRest((t1: D) => {})
|
||||
testRest((t1, t2, t3) => {})
|
||||
testRest((t1: D, t2, t3) => {})
|
||||
testRest((t1, t2: D, t3) => {})
|
||||
testRest((t2: D, ...t3) => {})
|
||||
testRest((t2, ...t3: D[]) => {})
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// @noImplicitAny: true
|
||||
|
||||
// simple case
|
||||
declare function simple(f: (a: number, b: number) => void): {}
|
||||
|
||||
simple((a: number, b) => {})
|
||||
simple((a, b: number) => {})
|
||||
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
////interface A {
|
||||
//// a: string;
|
||||
////}
|
||||
////declare function ctx(callback: (this: A) => string): string;
|
||||
////ctx(function () { return th/*1*/is./*2*/a });
|
||||
|
||||
goTo.marker('1');
|
||||
verify.quickInfoIs("this: A");
|
||||
goTo.marker('2');
|
||||
verify.memberListContains('a', '(property) A.a: string');
|
||||
|
||||
Reference in New Issue
Block a user