@@ -3504,15 +3504,19 @@ namespace ts {
35043504 return isPrivateWithinAmbient(memberDeclaration);
35053505 }
35063506
3507- function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type {
3507+ function getTypeOfVariableOrParameterOrProperty(symbol: Symbol, crazy?: boolean): Type {
3508+ const declaration = symbol.valueDeclaration;
3509+ if (crazy && declaration.kind === SyntaxKind.Parameter && (declaration as ParameterDeclaration).contextualType) {
3510+ // TODO: Doesn't widen of course
3511+ return getTypeFromTypeNode((declaration as ParameterDeclaration).contextualType);
3512+ }
35083513 const links = getSymbolLinks(symbol);
35093514 if (!links.type) {
35103515 // Handle prototype property
35113516 if (symbol.flags & SymbolFlags.Prototype) {
35123517 return links.type = getTypeOfPrototypeProperty(symbol);
35133518 }
35143519 // Handle catch clause variables
3515- const declaration = symbol.valueDeclaration;
35163520 if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
35173521 return links.type = anyType;
35183522 }
@@ -3695,13 +3699,16 @@ namespace ts {
36953699 return links.type;
36963700 }
36973701
3698- function getTypeOfInstantiatedSymbol(symbol: Symbol): Type {
3702+ function getTypeOfInstantiatedSymbol(symbol: Symbol, crazy?: boolean ): Type {
36993703 const links = getSymbolLinks(symbol);
3704+ if (crazy) {
3705+ return instantiateType(getTypeOfSymbol(links.target, crazy), links.mapper);
3706+ }
37003707 if (!links.type) {
37013708 if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
37023709 return unknownType;
37033710 }
3704- let type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
3711+ let type = instantiateType(getTypeOfSymbol(links.target, crazy ), links.mapper);
37053712 if (!popTypeResolution()) {
37063713 type = reportCircularityError(symbol);
37073714 }
@@ -3725,12 +3732,12 @@ namespace ts {
37253732 return anyType;
37263733 }
37273734
3728- function getTypeOfSymbol(symbol: Symbol): Type {
3735+ function getTypeOfSymbol(symbol: Symbol, crazy?: boolean ): Type {
37293736 if (symbol.flags & SymbolFlags.Instantiated) {
3730- return getTypeOfInstantiatedSymbol(symbol);
3737+ return getTypeOfInstantiatedSymbol(symbol, crazy );
37313738 }
37323739 if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) {
3733- return getTypeOfVariableOrParameterOrProperty(symbol);
3740+ return getTypeOfVariableOrParameterOrProperty(symbol, crazy );
37343741 }
37353742 if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
37363743 return getTypeOfFuncClassEnumModule(symbol);
@@ -9073,7 +9080,7 @@ namespace ts {
90739080 // We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
90749081 // parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
90759082 inferFromTypes(getIndexType(source), constraintType);
9076- inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
9083+ inferFromTypes(getUnionType(map(getPropertiesOfType(source), p => getTypeOfSymbol(p) )), getTemplateTypeFromMappedType(<MappedType>target));
90779084 return;
90789085 }
90799086 }
@@ -11262,7 +11269,7 @@ namespace ts {
1126211269 const argIndex = indexOf(args, arg);
1126311270 if (argIndex >= 0) {
1126411271 const signature = getResolvedOrAnySignature(callTarget);
11265- return getTypeAtPosition (signature, argIndex);
11272+ return getSpecialContextualTypeAtPosition (signature, argIndex);
1126611273 }
1126711274 return undefined;
1126811275 }
@@ -13097,7 +13104,7 @@ namespace ts {
1309713104 // If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
1309813105 if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
1309913106 // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
13100- const paramType = getTypeAtPosition (signature, i);
13107+ const paramType = getSpecialContextualTypeAtPosition (signature, i);
1310113108 let argType = getEffectiveArgumentType(node, i);
1310213109
1310313110 // If the effective argument type is 'undefined', there is no synthetic type
@@ -14121,8 +14128,8 @@ namespace ts {
1412114128 }
1412214129 }
1412314130
14124- function getTypeOfParameter(symbol: Symbol) {
14125- const type = getTypeOfSymbol(symbol);
14131+ function getTypeOfParameter(symbol: Symbol, crazy?: boolean ) {
14132+ const type = getTypeOfSymbol(symbol, crazy );
1412614133 if (strictNullChecks) {
1412714134 const declaration = symbol.valueDeclaration;
1412814135 if (declaration && (<VariableLikeDeclaration>declaration).initializer) {
@@ -14132,6 +14139,12 @@ namespace ts {
1413214139 return type;
1413314140 }
1413414141
14142+ function getSpecialContextualTypeAtPosition(signature: Signature, pos: number): Type {
14143+ return signature.hasRestParameter ?
14144+ pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos], /*crazy*/ true) : getRestTypeOfSignature(signature) :
14145+ pos < signature.parameters.length ? getTypeOfParameter(signature.parameters[pos], /*crazy*/ true) : anyType;
14146+ }
14147+
1413514148 function getTypeAtPosition(signature: Signature, pos: number): Type {
1413614149 return signature.hasRestParameter ?
1413714150 pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
0 commit comments