mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 21:06:50 -05:00
Merge pull request #14141 from Microsoft/contextualThisType
Typed 'this' in object literal methods
This commit is contained in:
@@ -259,6 +259,7 @@ namespace ts {
|
||||
let globalNumberType: ObjectType;
|
||||
let globalBooleanType: ObjectType;
|
||||
let globalRegExpType: ObjectType;
|
||||
let globalThisType: GenericType;
|
||||
let anyArrayType: Type;
|
||||
let autoArrayType: Type;
|
||||
let anyReadonlyArrayType: Type;
|
||||
@@ -434,6 +435,12 @@ namespace ts {
|
||||
ResolvedReturnType
|
||||
}
|
||||
|
||||
const enum CheckMode {
|
||||
Normal = 0, // Normal type checking
|
||||
SkipContextSensitive = 1, // Skip context sensitive function expressions
|
||||
Inferential = 2, // Inferential typing
|
||||
}
|
||||
|
||||
const builtinGlobals = createMap<Symbol>();
|
||||
builtinGlobals.set(undefinedSymbol.name, undefinedSymbol);
|
||||
|
||||
@@ -6083,6 +6090,11 @@ namespace ts {
|
||||
return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
|
||||
}
|
||||
|
||||
function getGlobalTypeOrUndefined(name: string, arity = 0): ObjectType {
|
||||
const symbol = getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined);
|
||||
return symbol && <GenericType>getTypeOfGlobalSymbol(symbol, arity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type that is inside a namespace at the global scope, e.g.
|
||||
* getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type
|
||||
@@ -9015,11 +9027,19 @@ namespace ts {
|
||||
return regularNew;
|
||||
}
|
||||
|
||||
function getWidenedProperty(prop: Symbol): Symbol {
|
||||
const original = getTypeOfSymbol(prop);
|
||||
const widened = getWidenedType(original);
|
||||
return widened === original ? prop : createSymbolWithType(prop, widened);
|
||||
}
|
||||
|
||||
function getWidenedTypeOfObjectLiteral(type: Type): Type {
|
||||
const members = transformTypeOfMembers(type, prop => {
|
||||
const widened = getWidenedType(prop);
|
||||
return prop === widened ? prop : widened;
|
||||
});
|
||||
const members = createMap<Symbol>();
|
||||
for (const prop of getPropertiesOfObjectType(type)) {
|
||||
// Since get accessors already widen their return value there is no need to
|
||||
// widen accessor based properties here.
|
||||
members.set(prop.name, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop) : prop);
|
||||
};
|
||||
const stringIndexInfo = getIndexInfoOfType(type, IndexKind.String);
|
||||
const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number);
|
||||
return createAnonymousType(type.symbol, members, emptyArray, emptyArray,
|
||||
@@ -10065,8 +10085,31 @@ namespace ts {
|
||||
return f(type) ? type : neverType;
|
||||
}
|
||||
|
||||
function mapType(type: Type, f: (t: Type) => Type): Type {
|
||||
return type.flags & TypeFlags.Union ? getUnionType(map((<UnionType>type).types, f)) : f(type);
|
||||
// Apply a mapping function to a type and return the resulting type. If the source type
|
||||
// is a union type, the mapping function is applied to each constituent type and a union
|
||||
// of the resulting types is returned.
|
||||
function mapType(type: Type, mapper: (t: Type) => Type): Type {
|
||||
if (!(type.flags & TypeFlags.Union)) {
|
||||
return mapper(type);
|
||||
}
|
||||
const types = (<UnionType>type).types;
|
||||
let mappedType: Type;
|
||||
let mappedTypes: Type[];
|
||||
for (const current of types) {
|
||||
const t = mapper(current);
|
||||
if (t) {
|
||||
if (!mappedType) {
|
||||
mappedType = t;
|
||||
}
|
||||
else if (!mappedTypes) {
|
||||
mappedTypes = [mappedType, t];
|
||||
}
|
||||
else {
|
||||
mappedTypes.push(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappedTypes ? getUnionType(mappedTypes) : mappedType;
|
||||
}
|
||||
|
||||
function extractTypesOfKind(type: Type, kind: TypeFlags) {
|
||||
@@ -11502,8 +11545,29 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getContainingObjectLiteral(func: FunctionLikeDeclaration) {
|
||||
return (func.kind === SyntaxKind.MethodDeclaration ||
|
||||
func.kind === SyntaxKind.GetAccessor ||
|
||||
func.kind === SyntaxKind.SetAccessor) && func.parent.kind === SyntaxKind.ObjectLiteralExpression ? <ObjectLiteralExpression>func.parent :
|
||||
func.kind === SyntaxKind.FunctionExpression && func.parent.kind === SyntaxKind.PropertyAssignment ? <ObjectLiteralExpression>func.parent.parent :
|
||||
undefined;
|
||||
}
|
||||
|
||||
function getThisTypeArgument(type: Type): Type {
|
||||
return getObjectFlags(type) & ObjectFlags.Reference && (<TypeReference>type).target === globalThisType ? (<TypeReference>type).typeArguments[0] : undefined;
|
||||
}
|
||||
|
||||
function getThisTypeFromContextualType(type: Type): Type {
|
||||
return mapType(type, t => {
|
||||
return t.flags & TypeFlags.Intersection ? forEach((<IntersectionType>t).types, getThisTypeArgument) : getThisTypeArgument(t);
|
||||
});
|
||||
}
|
||||
|
||||
function getContextualThisParameterType(func: FunctionLikeDeclaration): Type {
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func) && func.kind !== SyntaxKind.ArrowFunction) {
|
||||
if (func.kind === SyntaxKind.ArrowFunction) {
|
||||
return undefined;
|
||||
}
|
||||
if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
|
||||
const contextualSignature = getContextualSignature(func);
|
||||
if (contextualSignature) {
|
||||
const thisParameter = contextualSignature.thisParameter;
|
||||
@@ -11512,6 +11576,40 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compilerOptions.noImplicitThis) {
|
||||
const containingLiteral = getContainingObjectLiteral(func);
|
||||
if (containingLiteral) {
|
||||
// We have an object literal method. Check if the containing object literal has a contextual type
|
||||
// that includes a ThisType<T>. If so, T is the contextual type for 'this'. We continue looking in
|
||||
// any directly enclosing object literals.
|
||||
const contextualType = getApparentTypeOfContextualType(containingLiteral);
|
||||
let literal = containingLiteral;
|
||||
let type = contextualType;
|
||||
while (type) {
|
||||
const thisType = getThisTypeFromContextualType(type);
|
||||
if (thisType) {
|
||||
return instantiateType(thisType, getContextualMapper(containingLiteral));
|
||||
}
|
||||
if (literal.parent.kind !== SyntaxKind.PropertyAssignment) {
|
||||
break;
|
||||
}
|
||||
literal = <ObjectLiteralExpression>literal.parent.parent;
|
||||
type = getApparentTypeOfContextualType(literal);
|
||||
}
|
||||
// There was no contextual ThisType<T> for the containing object literal, so the contextual type
|
||||
// for 'this' is the contextual type for the containing object literal or the type of the object
|
||||
// literal itself.
|
||||
return contextualType || checkExpressionCached(containingLiteral);
|
||||
}
|
||||
// In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
|
||||
// contextual type for 'this' is 'obj'.
|
||||
if (func.parent.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>func.parent).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
const target = (<BinaryExpression>func.parent).left;
|
||||
if (target.kind === SyntaxKind.PropertyAccessExpression || target.kind === SyntaxKind.ElementAccessExpression) {
|
||||
return checkExpressionCached((<PropertyAccessExpression | ElementAccessExpression>target).expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -11710,42 +11808,15 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Apply a mapping function to a contextual type and return the resulting type. If the contextual type
|
||||
// is a union type, the mapping function is applied to each constituent type and a union of the resulting
|
||||
// types is returned.
|
||||
function applyToContextualType(type: Type, mapper: (t: Type) => Type): Type {
|
||||
if (!(type.flags & TypeFlags.Union)) {
|
||||
return mapper(type);
|
||||
}
|
||||
const types = (<UnionType>type).types;
|
||||
let mappedType: Type;
|
||||
let mappedTypes: Type[];
|
||||
for (const current of types) {
|
||||
const t = mapper(current);
|
||||
if (t) {
|
||||
if (!mappedType) {
|
||||
mappedType = t;
|
||||
}
|
||||
else if (!mappedTypes) {
|
||||
mappedTypes = [mappedType, t];
|
||||
}
|
||||
else {
|
||||
mappedTypes.push(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return mappedTypes ? getUnionType(mappedTypes) : mappedType;
|
||||
}
|
||||
|
||||
function getTypeOfPropertyOfContextualType(type: Type, name: string) {
|
||||
return applyToContextualType(type, t => {
|
||||
return mapType(type, t => {
|
||||
const prop = t.flags & TypeFlags.StructuredType ? getPropertyOfType(t, name) : undefined;
|
||||
return prop ? getTypeOfSymbol(prop) : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
function getIndexTypeOfContextualType(type: Type, kind: IndexKind) {
|
||||
return applyToContextualType(type, t => getIndexTypeOfStructuredType(t, kind));
|
||||
return mapType(type, t => getIndexTypeOfStructuredType(t, kind));
|
||||
}
|
||||
|
||||
// Return true if the given contextual type is a tuple-like type
|
||||
@@ -11904,6 +11975,16 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getContextualMapper(node: Node) {
|
||||
while (node) {
|
||||
if (node.contextualMapper) {
|
||||
return node.contextualMapper;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
return identityMapper;
|
||||
}
|
||||
|
||||
// If the given type is an object or union type, if that type has a single signature, and if
|
||||
// that signature is non-generic, return the signature. Otherwise return undefined.
|
||||
function getNonGenericSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
|
||||
@@ -11994,31 +12075,12 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if the mapper implies an inference context. Specifically, there are 4 possible values
|
||||
* for a mapper. Let's go through each one of them:
|
||||
*
|
||||
* 1. undefined - this means we are not doing inferential typing, but we may do contextual typing,
|
||||
* which could cause us to assign a parameter a type
|
||||
* 2. identityMapper - means we want to avoid assigning a parameter a type, whether or not we are in
|
||||
* inferential typing (context is undefined for the identityMapper)
|
||||
* 3. a mapper created by createInferenceMapper - we are doing inferential typing, we want to assign
|
||||
* types to parameters and fix type parameters (context is defined)
|
||||
* 4. an instantiation mapper created by createTypeMapper or createTypeEraser - this should never be
|
||||
* passed as the contextual mapper when checking an expression (context is undefined for these)
|
||||
*
|
||||
* isInferentialContext is detecting if we are in case 3
|
||||
*/
|
||||
function isInferentialContext(mapper: TypeMapper) {
|
||||
return mapper && mapper.context;
|
||||
}
|
||||
|
||||
function checkSpreadExpression(node: SpreadElement, contextualMapper?: TypeMapper): Type {
|
||||
function checkSpreadExpression(node: SpreadElement, checkMode?: CheckMode): Type {
|
||||
if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.SpreadIncludes);
|
||||
}
|
||||
|
||||
const arrayOrIterableType = checkExpression(node.expression, contextualMapper);
|
||||
const arrayOrIterableType = checkExpression(node.expression, checkMode);
|
||||
return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterable*/ false);
|
||||
}
|
||||
|
||||
@@ -12027,7 +12089,7 @@ namespace ts {
|
||||
(node.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>node).operatorToken.kind === SyntaxKind.EqualsToken);
|
||||
}
|
||||
|
||||
function checkArrayLiteral(node: ArrayLiteralExpression, contextualMapper?: TypeMapper): Type {
|
||||
function checkArrayLiteral(node: ArrayLiteralExpression, checkMode?: CheckMode): Type {
|
||||
const elements = node.elements;
|
||||
let hasSpreadElement = false;
|
||||
const elementTypes: Type[] = [];
|
||||
@@ -12046,7 +12108,7 @@ namespace ts {
|
||||
// get the contextual element type from it. So we do something similar to
|
||||
// getContextualTypeForElementExpression, which will crucially not error
|
||||
// if there is no index type / iterated type.
|
||||
const restArrayType = checkExpression((<SpreadElement>e).expression, contextualMapper);
|
||||
const restArrayType = checkExpression((<SpreadElement>e).expression, checkMode);
|
||||
const restElementType = getIndexTypeOfType(restArrayType, IndexKind.Number) ||
|
||||
getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterable*/ false, /*checkAssignability*/ false);
|
||||
if (restElementType) {
|
||||
@@ -12054,7 +12116,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const type = checkExpressionForMutableLocation(e, contextualMapper);
|
||||
const type = checkExpressionForMutableLocation(e, checkMode);
|
||||
elementTypes.push(type);
|
||||
}
|
||||
hasSpreadElement = hasSpreadElement || e.kind === SyntaxKind.SpreadElement;
|
||||
@@ -12169,7 +12231,7 @@ namespace ts {
|
||||
return createIndexInfo(unionType, /*isReadonly*/ false);
|
||||
}
|
||||
|
||||
function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type {
|
||||
function checkObjectLiteral(node: ObjectLiteralExpression, checkMode?: CheckMode): Type {
|
||||
const inDestructuringPattern = isAssignmentTarget(node);
|
||||
// Grammar checking
|
||||
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
|
||||
@@ -12196,14 +12258,14 @@ namespace ts {
|
||||
isObjectLiteralMethod(memberDecl)) {
|
||||
let type: Type;
|
||||
if (memberDecl.kind === SyntaxKind.PropertyAssignment) {
|
||||
type = checkPropertyAssignment(<PropertyAssignment>memberDecl, contextualMapper);
|
||||
type = checkPropertyAssignment(<PropertyAssignment>memberDecl, checkMode);
|
||||
}
|
||||
else if (memberDecl.kind === SyntaxKind.MethodDeclaration) {
|
||||
type = checkObjectLiteralMethod(<MethodDeclaration>memberDecl, contextualMapper);
|
||||
type = checkObjectLiteralMethod(<MethodDeclaration>memberDecl, checkMode);
|
||||
}
|
||||
else {
|
||||
Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment);
|
||||
type = checkExpressionForMutableLocation((<ShorthandPropertyAssignment>memberDecl).name, contextualMapper);
|
||||
type = checkExpressionForMutableLocation((<ShorthandPropertyAssignment>memberDecl).name, checkMode);
|
||||
}
|
||||
|
||||
typeFlags |= type.flags;
|
||||
@@ -12272,7 +12334,7 @@ namespace ts {
|
||||
// A set accessor declaration is processed in the same manner
|
||||
// as an ordinary function declaration with a single parameter and a Void return type.
|
||||
Debug.assert(memberDecl.kind === SyntaxKind.GetAccessor || memberDecl.kind === SyntaxKind.SetAccessor);
|
||||
checkAccessorDeclaration(<AccessorDeclaration>memberDecl);
|
||||
checkNodeDeferred(memberDecl);
|
||||
}
|
||||
|
||||
if (hasDynamicName(memberDecl)) {
|
||||
@@ -12409,7 +12471,7 @@ namespace ts {
|
||||
* @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral,
|
||||
* which also calls getSpreadType.
|
||||
*/
|
||||
function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean, contextualMapper?: TypeMapper) {
|
||||
function createJsxAttributesTypeFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement, filter?: (symbol: Symbol) => boolean, checkMode?: CheckMode) {
|
||||
const attributes = openingLikeElement.attributes;
|
||||
let attributesTable = createMap<Symbol>();
|
||||
let spread: Type = emptyObjectType;
|
||||
@@ -12418,7 +12480,7 @@ namespace ts {
|
||||
const member = attributeDecl.symbol;
|
||||
if (isJsxAttribute(attributeDecl)) {
|
||||
const exprType = attributeDecl.initializer ?
|
||||
checkExpression(attributeDecl.initializer, contextualMapper) :
|
||||
checkExpression(attributeDecl.initializer, checkMode) :
|
||||
trueType; // <Elem attr /> is sugar for <Elem attr={true} />
|
||||
|
||||
const attributeSymbol = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.name);
|
||||
@@ -12489,8 +12551,8 @@ namespace ts {
|
||||
* (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
|
||||
* @param node a JSXAttributes to be resolved of its type
|
||||
*/
|
||||
function checkJsxAttributes(node: JsxAttributes, contextualMapper?: TypeMapper) {
|
||||
return createJsxAttributesTypeFromAttributesProperty(node.parent as JsxOpeningLikeElement, /*filter*/ undefined, contextualMapper);
|
||||
function checkJsxAttributes(node: JsxAttributes, checkMode?: CheckMode) {
|
||||
return createJsxAttributesTypeFromAttributesProperty(node.parent as JsxOpeningLikeElement, /*filter*/ undefined, checkMode);
|
||||
}
|
||||
|
||||
function getJsxType(name: string) {
|
||||
@@ -12983,9 +13045,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkJsxExpression(node: JsxExpression, contextualMapper?: TypeMapper) {
|
||||
function checkJsxExpression(node: JsxExpression, checkMode?: CheckMode) {
|
||||
if (node.expression) {
|
||||
const type = checkExpression(node.expression, contextualMapper);
|
||||
const type = checkExpression(node.expression, checkMode);
|
||||
if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
|
||||
error(node, Diagnostics.JSX_spread_child_must_be_an_array_type, node.toString(), typeToString(type));
|
||||
}
|
||||
@@ -14846,9 +14908,9 @@ namespace ts {
|
||||
return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType;
|
||||
}
|
||||
|
||||
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper) {
|
||||
function assignContextualParameterTypes(signature: Signature, context: Signature, mapper: TypeMapper, checkMode: CheckMode) {
|
||||
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
||||
if (isInferentialContext(mapper)) {
|
||||
if (checkMode === CheckMode.Inferential) {
|
||||
for (let i = 0; i < len; i++) {
|
||||
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
|
||||
if (declaration.type) {
|
||||
@@ -14862,21 +14924,21 @@ namespace ts {
|
||||
if (!parameter) {
|
||||
signature.thisParameter = createSymbolWithType(context.thisParameter, undefined);
|
||||
}
|
||||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper);
|
||||
assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter), mapper, checkMode);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < len; i++) {
|
||||
const parameter = signature.parameters[i];
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
const contextualParameterType = getTypeAtPosition(context, i);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode);
|
||||
}
|
||||
}
|
||||
if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) {
|
||||
const parameter = lastOrUndefined(signature.parameters);
|
||||
if (!(<ParameterDeclaration>parameter.valueDeclaration).type) {
|
||||
const contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters));
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper);
|
||||
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper, checkMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14896,7 +14958,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper) {
|
||||
function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper, checkMode: CheckMode) {
|
||||
const links = getSymbolLinks(parameter);
|
||||
if (!links.type) {
|
||||
links.type = instantiateType(contextualType, mapper);
|
||||
@@ -14908,7 +14970,7 @@ namespace ts {
|
||||
}
|
||||
assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
|
||||
}
|
||||
else if (isInferentialContext(mapper)) {
|
||||
else if (checkMode === CheckMode.Inferential) {
|
||||
// Even if the parameter already has a type, it might be because it was given a type while
|
||||
// processing the function as an argument to a prior signature during overload resolution.
|
||||
// If this was the case, it may have caused some type parameters to be fixed. So here,
|
||||
@@ -14976,7 +15038,7 @@ namespace ts {
|
||||
return promiseType;
|
||||
}
|
||||
|
||||
function getReturnTypeFromBody(func: FunctionLikeDeclaration, contextualMapper?: TypeMapper): Type {
|
||||
function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type {
|
||||
const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
|
||||
if (!func.body) {
|
||||
return unknownType;
|
||||
@@ -14985,7 +15047,7 @@ namespace ts {
|
||||
const functionFlags = getFunctionFlags(func);
|
||||
let type: Type;
|
||||
if (func.body.kind !== SyntaxKind.Block) {
|
||||
type = checkExpressionCached(<Expression>func.body, contextualMapper);
|
||||
type = checkExpressionCached(<Expression>func.body, checkMode);
|
||||
if (functionFlags & FunctionFlags.Async) {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
@@ -14997,7 +15059,7 @@ namespace ts {
|
||||
else {
|
||||
let types: Type[];
|
||||
if (functionFlags & FunctionFlags.Generator) { // Generator or AsyncGenerator function
|
||||
types = checkAndAggregateYieldOperandTypes(func, contextualMapper);
|
||||
types = checkAndAggregateYieldOperandTypes(func, checkMode);
|
||||
if (types.length === 0) {
|
||||
const iterableIteratorAny = functionFlags & FunctionFlags.Async
|
||||
? createAsyncIterableIteratorType(anyType) // AsyncGenerator function
|
||||
@@ -15010,7 +15072,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
types = checkAndAggregateReturnExpressionTypes(func, contextualMapper);
|
||||
types = checkAndAggregateReturnExpressionTypes(func, checkMode);
|
||||
if (!types) {
|
||||
// For an async function, the return type will not be never, but rather a Promise for never.
|
||||
return functionFlags & FunctionFlags.Async
|
||||
@@ -15054,13 +15116,13 @@ namespace ts {
|
||||
: widenedType; // Generator function, AsyncGenerator function, or normal function
|
||||
}
|
||||
|
||||
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, contextualMapper: TypeMapper): Type[] {
|
||||
function checkAndAggregateYieldOperandTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] {
|
||||
const aggregatedTypes: Type[] = [];
|
||||
const functionFlags = getFunctionFlags(func);
|
||||
forEachYieldExpression(<Block>func.body, yieldExpression => {
|
||||
const expr = yieldExpression.expression;
|
||||
if (expr) {
|
||||
let type = checkExpressionCached(expr, contextualMapper);
|
||||
let type = checkExpressionCached(expr, checkMode);
|
||||
if (yieldExpression.asteriskToken) {
|
||||
// A yield* expression effectively yields everything that its operand yields
|
||||
type = checkIteratedTypeOrElementType(type, yieldExpression.expression, /*allowStringInput*/ false, (functionFlags & FunctionFlags.Async) !== 0);
|
||||
@@ -15100,7 +15162,7 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, contextualMapper: TypeMapper): Type[] {
|
||||
function checkAndAggregateReturnExpressionTypes(func: FunctionLikeDeclaration, checkMode: CheckMode): Type[] {
|
||||
const functionFlags = getFunctionFlags(func);
|
||||
const aggregatedTypes: Type[] = [];
|
||||
let hasReturnWithNoExpression = functionHasImplicitReturn(func);
|
||||
@@ -15108,7 +15170,7 @@ namespace ts {
|
||||
forEachReturnStatement(<Block>func.body, returnStatement => {
|
||||
const expr = returnStatement.expression;
|
||||
if (expr) {
|
||||
let type = checkExpressionCached(expr, contextualMapper);
|
||||
let type = checkExpressionCached(expr, checkMode);
|
||||
if (functionFlags & FunctionFlags.Async) {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
@@ -15195,7 +15257,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, contextualMapper?: TypeMapper): Type {
|
||||
function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, checkMode?: CheckMode): Type {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
|
||||
// Grammar checking
|
||||
@@ -15205,7 +15267,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// The identityMapper object is used to indicate that function expressions are wildcards
|
||||
if (contextualMapper === identityMapper && isContextSensitive(node)) {
|
||||
if (checkMode === CheckMode.SkipContextSensitive && isContextSensitive(node)) {
|
||||
checkNodeDeferred(node);
|
||||
return anyFunctionType;
|
||||
}
|
||||
@@ -15213,7 +15275,7 @@ namespace ts {
|
||||
const links = getNodeLinks(node);
|
||||
const type = getTypeOfSymbol(node.symbol);
|
||||
const contextSensitive = isContextSensitive(node);
|
||||
const mightFixTypeParameters = contextSensitive && isInferentialContext(contextualMapper);
|
||||
const mightFixTypeParameters = contextSensitive && checkMode === CheckMode.Inferential;
|
||||
|
||||
// Check if function expression is contextually typed and assign parameter types if so.
|
||||
// See the comment in assignTypeToParameterAndFixTypeParameters to understand why we need to
|
||||
@@ -15229,10 +15291,10 @@ namespace ts {
|
||||
if (contextualSignature) {
|
||||
const signature = getSignaturesOfType(type, SignatureKind.Call)[0];
|
||||
if (contextSensitive) {
|
||||
assignContextualParameterTypes(signature, contextualSignature, contextualMapper || identityMapper);
|
||||
assignContextualParameterTypes(signature, contextualSignature, getContextualMapper(node), checkMode);
|
||||
}
|
||||
if (mightFixTypeParameters || !node.type && !signature.resolvedReturnType) {
|
||||
const returnType = getReturnTypeFromBody(node, contextualMapper);
|
||||
const returnType = getReturnTypeFromBody(node, checkMode);
|
||||
if (!signature.resolvedReturnType) {
|
||||
signature.resolvedReturnType = returnType;
|
||||
}
|
||||
@@ -15608,7 +15670,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, checkMode?: CheckMode): Type {
|
||||
if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.Read);
|
||||
}
|
||||
@@ -15619,13 +15681,13 @@ namespace ts {
|
||||
const elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterable*/ false) || unknownType;
|
||||
const elements = node.elements;
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, contextualMapper);
|
||||
checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode);
|
||||
}
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
function checkArrayLiteralDestructuringElementAssignment(node: ArrayLiteralExpression, sourceType: Type,
|
||||
elementIndex: number, elementType: Type, contextualMapper?: TypeMapper) {
|
||||
elementIndex: number, elementType: Type, checkMode?: CheckMode) {
|
||||
const elements = node.elements;
|
||||
const element = elements[elementIndex];
|
||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
@@ -15637,7 +15699,7 @@ namespace ts {
|
||||
? getTypeOfPropertyOfType(sourceType, propName)
|
||||
: elementType;
|
||||
if (type) {
|
||||
return checkDestructuringAssignment(element, type, contextualMapper);
|
||||
return checkDestructuringAssignment(element, type, checkMode);
|
||||
}
|
||||
else {
|
||||
// We still need to check element expression here because we may need to set appropriate flag on the expression
|
||||
@@ -15661,7 +15723,7 @@ namespace ts {
|
||||
error((<BinaryExpression>restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
}
|
||||
else {
|
||||
return checkDestructuringAssignment(restExpression, createArrayType(elementType), contextualMapper);
|
||||
return checkDestructuringAssignment(restExpression, createArrayType(elementType), checkMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15669,7 +15731,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, checkMode?: CheckMode): Type {
|
||||
let target: Expression;
|
||||
if (exprOrAssignment.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const prop = <ShorthandPropertyAssignment>exprOrAssignment;
|
||||
@@ -15680,7 +15742,7 @@ namespace ts {
|
||||
!(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & TypeFlags.Undefined)) {
|
||||
sourceType = getTypeWithFacts(sourceType, TypeFacts.NEUndefined);
|
||||
}
|
||||
checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, contextualMapper);
|
||||
checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode);
|
||||
}
|
||||
target = (<ShorthandPropertyAssignment>exprOrAssignment).name;
|
||||
}
|
||||
@@ -15689,20 +15751,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
checkBinaryExpression(<BinaryExpression>target, contextualMapper);
|
||||
checkBinaryExpression(<BinaryExpression>target, checkMode);
|
||||
target = (<BinaryExpression>target).left;
|
||||
}
|
||||
if (target.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
return checkObjectLiteralAssignment(<ObjectLiteralExpression>target, sourceType);
|
||||
}
|
||||
if (target.kind === SyntaxKind.ArrayLiteralExpression) {
|
||||
return checkArrayLiteralAssignment(<ArrayLiteralExpression>target, sourceType, contextualMapper);
|
||||
return checkArrayLiteralAssignment(<ArrayLiteralExpression>target, sourceType, checkMode);
|
||||
}
|
||||
return checkReferenceAssignment(target, sourceType, contextualMapper);
|
||||
return checkReferenceAssignment(target, sourceType, checkMode);
|
||||
}
|
||||
|
||||
function checkReferenceAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
const targetType = checkExpression(target, contextualMapper);
|
||||
function checkReferenceAssignment(target: Expression, sourceType: Type, checkMode?: CheckMode): Type {
|
||||
const targetType = checkExpression(target, checkMode);
|
||||
const error = target.parent.kind === SyntaxKind.SpreadAssignment ?
|
||||
Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
|
||||
Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
|
||||
@@ -15790,17 +15852,17 @@ namespace ts {
|
||||
getUnionType([type1, type2], /*subtypeReduction*/ true);
|
||||
}
|
||||
|
||||
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
|
||||
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
|
||||
function checkBinaryExpression(node: BinaryExpression, checkMode?: CheckMode) {
|
||||
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node);
|
||||
}
|
||||
|
||||
function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, contextualMapper?: TypeMapper, errorNode?: Node) {
|
||||
function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, checkMode?: CheckMode, errorNode?: Node) {
|
||||
const operator = operatorToken.kind;
|
||||
if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
return checkDestructuringAssignment(left, checkExpression(right, contextualMapper), contextualMapper);
|
||||
return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode);
|
||||
}
|
||||
let leftType = checkExpression(left, contextualMapper);
|
||||
let rightType = checkExpression(right, contextualMapper);
|
||||
let leftType = checkExpression(left, checkMode);
|
||||
let rightType = checkExpression(right, checkMode);
|
||||
switch (operator) {
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.AsteriskAsteriskToken:
|
||||
@@ -16067,10 +16129,10 @@ namespace ts {
|
||||
return anyType;
|
||||
}
|
||||
|
||||
function checkConditionalExpression(node: ConditionalExpression, contextualMapper?: TypeMapper): Type {
|
||||
function checkConditionalExpression(node: ConditionalExpression, checkMode?: CheckMode): Type {
|
||||
checkExpression(node.condition);
|
||||
const type1 = checkExpression(node.whenTrue, contextualMapper);
|
||||
const type2 = checkExpression(node.whenFalse, contextualMapper);
|
||||
const type1 = checkExpression(node.whenTrue, checkMode);
|
||||
const type2 = checkExpression(node.whenFalse, checkMode);
|
||||
return getBestChoiceType(type1, type2);
|
||||
}
|
||||
|
||||
@@ -16103,15 +16165,20 @@ namespace ts {
|
||||
return stringType;
|
||||
}
|
||||
|
||||
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper?: TypeMapper): Type {
|
||||
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper: TypeMapper): Type {
|
||||
const saveContextualType = node.contextualType;
|
||||
const saveContextualMapper = node.contextualMapper;
|
||||
node.contextualType = contextualType;
|
||||
const result = checkExpression(node, contextualMapper);
|
||||
node.contextualMapper = contextualMapper;
|
||||
const checkMode = contextualMapper === identityMapper ? CheckMode.SkipContextSensitive :
|
||||
contextualMapper ? CheckMode.Inferential : CheckMode.Normal;
|
||||
const result = checkExpression(node, checkMode);
|
||||
node.contextualType = saveContextualType;
|
||||
node.contextualMapper = saveContextualMapper;
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkExpressionCached(node: Expression, contextualMapper?: TypeMapper): Type {
|
||||
function checkExpressionCached(node: Expression, checkMode?: CheckMode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
// When computing a type that we're going to cache, we need to ignore any ongoing control flow
|
||||
@@ -16119,7 +16186,7 @@ namespace ts {
|
||||
// to the top of the stack ensures all transient types are computed from a known point.
|
||||
const saveFlowLoopStart = flowLoopStart;
|
||||
flowLoopStart = flowLoopCount;
|
||||
links.resolvedType = checkExpression(node, contextualMapper);
|
||||
links.resolvedType = checkExpression(node, checkMode);
|
||||
flowLoopStart = saveFlowLoopStart;
|
||||
}
|
||||
return links.resolvedType;
|
||||
@@ -16154,12 +16221,12 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkExpressionForMutableLocation(node: Expression, contextualMapper?: TypeMapper): Type {
|
||||
const type = checkExpression(node, contextualMapper);
|
||||
function checkExpressionForMutableLocation(node: Expression, checkMode?: CheckMode): Type {
|
||||
const type = checkExpression(node, checkMode);
|
||||
return isTypeAssertion(node) || isLiteralContextualType(getContextualType(node)) ? type : getWidenedLiteralType(type);
|
||||
}
|
||||
|
||||
function checkPropertyAssignment(node: PropertyAssignment, contextualMapper?: TypeMapper): Type {
|
||||
function checkPropertyAssignment(node: PropertyAssignment, checkMode?: CheckMode): Type {
|
||||
// Do not use hasDynamicName here, because that returns false for well known symbols.
|
||||
// We want to perform checkComputedPropertyName for all computed properties, including
|
||||
// well known symbols.
|
||||
@@ -16167,10 +16234,10 @@ namespace ts {
|
||||
checkComputedPropertyName(<ComputedPropertyName>node.name);
|
||||
}
|
||||
|
||||
return checkExpressionForMutableLocation((<PropertyAssignment>node).initializer, contextualMapper);
|
||||
return checkExpressionForMutableLocation((<PropertyAssignment>node).initializer, checkMode);
|
||||
}
|
||||
|
||||
function checkObjectLiteralMethod(node: MethodDeclaration, contextualMapper?: TypeMapper): Type {
|
||||
function checkObjectLiteralMethod(node: MethodDeclaration, checkMode?: CheckMode): Type {
|
||||
// Grammar checking
|
||||
checkGrammarMethod(node);
|
||||
|
||||
@@ -16181,19 +16248,19 @@ namespace ts {
|
||||
checkComputedPropertyName(<ComputedPropertyName>node.name);
|
||||
}
|
||||
|
||||
const uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, contextualMapper);
|
||||
return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, contextualMapper);
|
||||
const uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
|
||||
return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
|
||||
}
|
||||
|
||||
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration, type: Type, contextualMapper?: TypeMapper) {
|
||||
if (isInferentialContext(contextualMapper)) {
|
||||
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration, type: Type, checkMode?: CheckMode) {
|
||||
if (checkMode === CheckMode.Inferential) {
|
||||
const signature = getSingleCallSignature(type);
|
||||
if (signature && signature.typeParameters) {
|
||||
const contextualType = getApparentTypeOfContextualType(<Expression>node);
|
||||
if (contextualType) {
|
||||
const contextualSignature = getSingleCallSignature(contextualType);
|
||||
if (contextualSignature && !contextualSignature.typeParameters) {
|
||||
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper));
|
||||
return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16229,14 +16296,14 @@ namespace ts {
|
||||
// object, it serves as an indicator that all contained function and arrow expressions should be considered to
|
||||
// have the wildcard function type; this form of type check is used during overload resolution to exclude
|
||||
// contextually typed function and arrow expressions in the initial phase.
|
||||
function checkExpression(node: Expression | QualifiedName, contextualMapper?: TypeMapper): Type {
|
||||
function checkExpression(node: Expression | QualifiedName, checkMode?: CheckMode): Type {
|
||||
let type: Type;
|
||||
if (node.kind === SyntaxKind.QualifiedName) {
|
||||
type = checkQualifiedName(<QualifiedName>node);
|
||||
}
|
||||
else {
|
||||
const uninstantiatedType = checkExpressionWorker(<Expression>node, contextualMapper);
|
||||
type = instantiateTypeWithSingleGenericCallSignature(<Expression>node, uninstantiatedType, contextualMapper);
|
||||
const uninstantiatedType = checkExpressionWorker(<Expression>node, checkMode);
|
||||
type = instantiateTypeWithSingleGenericCallSignature(<Expression>node, uninstantiatedType, checkMode);
|
||||
}
|
||||
|
||||
if (isConstEnumObjectType(type)) {
|
||||
@@ -16256,7 +16323,7 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function checkExpressionWorker(node: Expression, contextualMapper: TypeMapper): Type {
|
||||
function checkExpressionWorker(node: Expression, checkMode: CheckMode): Type {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return checkIdentifier(<Identifier>node);
|
||||
@@ -16278,9 +16345,9 @@ namespace ts {
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
return globalRegExpType;
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return checkArrayLiteral(<ArrayLiteralExpression>node, contextualMapper);
|
||||
return checkArrayLiteral(<ArrayLiteralExpression>node, checkMode);
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return checkObjectLiteral(<ObjectLiteralExpression>node, contextualMapper);
|
||||
return checkObjectLiteral(<ObjectLiteralExpression>node, checkMode);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return checkPropertyAccessExpression(<PropertyAccessExpression>node);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
@@ -16291,12 +16358,12 @@ namespace ts {
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return checkExpression((<ParenthesizedExpression>node).expression, contextualMapper);
|
||||
return checkExpression((<ParenthesizedExpression>node).expression, checkMode);
|
||||
case SyntaxKind.ClassExpression:
|
||||
return checkClassExpression(<ClassExpression>node);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression>node, contextualMapper);
|
||||
return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression>node, checkMode);
|
||||
case SyntaxKind.TypeOfExpression:
|
||||
return checkTypeOfExpression(<TypeOfExpression>node);
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
@@ -16317,23 +16384,23 @@ namespace ts {
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
return checkPostfixUnaryExpression(<PostfixUnaryExpression>node);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return checkBinaryExpression(<BinaryExpression>node, contextualMapper);
|
||||
return checkBinaryExpression(<BinaryExpression>node, checkMode);
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
return checkConditionalExpression(<ConditionalExpression>node, contextualMapper);
|
||||
return checkConditionalExpression(<ConditionalExpression>node, checkMode);
|
||||
case SyntaxKind.SpreadElement:
|
||||
return checkSpreadExpression(<SpreadElement>node, contextualMapper);
|
||||
return checkSpreadExpression(<SpreadElement>node, checkMode);
|
||||
case SyntaxKind.OmittedExpression:
|
||||
return undefinedWideningType;
|
||||
case SyntaxKind.YieldExpression:
|
||||
return checkYieldExpression(<YieldExpression>node);
|
||||
case SyntaxKind.JsxExpression:
|
||||
return checkJsxExpression(<JsxExpression>node, contextualMapper);
|
||||
return checkJsxExpression(<JsxExpression>node, checkMode);
|
||||
case SyntaxKind.JsxElement:
|
||||
return checkJsxElement(<JsxElement>node);
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
return checkJsxSelfClosingElement(<JsxSelfClosingElement>node);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return checkJsxAttributes(<JsxAttributes>node, contextualMapper);
|
||||
return checkJsxAttributes(<JsxAttributes>node, checkMode);
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
Debug.fail("Shouldn't ever directly check a JsxOpeningElement");
|
||||
}
|
||||
@@ -16927,13 +16994,8 @@ namespace ts {
|
||||
checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
|
||||
}
|
||||
}
|
||||
if (node.parent.kind !== SyntaxKind.ObjectLiteralExpression) {
|
||||
checkSourceElement(node.body);
|
||||
registerForUnusedIdentifiersCheck(node);
|
||||
}
|
||||
else {
|
||||
checkNodeDeferred(node);
|
||||
}
|
||||
checkSourceElement(node.body);
|
||||
registerForUnusedIdentifiersCheck(node);
|
||||
}
|
||||
|
||||
function checkAccessorDeclarationTypesIdentical(first: AccessorDeclaration, second: AccessorDeclaration, getAnnotatedType: (a: AccessorDeclaration) => Type, message: DiagnosticMessage) {
|
||||
@@ -16944,11 +17006,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function checkAccessorDeferred(node: AccessorDeclaration) {
|
||||
checkSourceElement(node.body);
|
||||
registerForUnusedIdentifiersCheck(node);
|
||||
}
|
||||
|
||||
function checkMissingDeclaration(node: Node) {
|
||||
checkDecorators(node);
|
||||
}
|
||||
@@ -20615,7 +20672,7 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
checkAccessorDeferred(<AccessorDeclaration>node);
|
||||
checkAccessorDeclaration(<AccessorDeclaration>node);
|
||||
break;
|
||||
case SyntaxKind.ClassExpression:
|
||||
checkClassExpressionDeferred(<ClassExpression>node);
|
||||
@@ -21972,9 +22029,9 @@ namespace ts {
|
||||
anyArrayType = createArrayType(anyType);
|
||||
autoArrayType = createArrayType(autoType);
|
||||
|
||||
const symbol = getGlobalSymbol("ReadonlyArray", SymbolFlags.Type, /*diagnostic*/ undefined);
|
||||
globalReadonlyArrayType = symbol && <GenericType>getTypeOfGlobalSymbol(symbol, /*arity*/ 1);
|
||||
globalReadonlyArrayType = <GenericType>getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1);
|
||||
anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
|
||||
globalThisType = <GenericType>getGlobalTypeOrUndefined("ThisType", /*arity*/ 1);
|
||||
}
|
||||
|
||||
function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
|
||||
|
||||
@@ -519,6 +519,8 @@
|
||||
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
|
||||
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
|
||||
/* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms)
|
||||
/* @internal */ contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
}
|
||||
|
||||
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
|
||||
@@ -963,7 +965,6 @@
|
||||
|
||||
export interface Expression extends Node {
|
||||
_expressionBrand: any;
|
||||
contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
|
||||
}
|
||||
|
||||
export interface OmittedExpression extends Expression {
|
||||
|
||||
11
src/lib/es5.d.ts
vendored
11
src/lib/es5.d.ts
vendored
@@ -147,7 +147,7 @@ interface ObjectConstructor {
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* @param properties JavaScript object that contains one or more property descriptors.
|
||||
*/
|
||||
create(o: object | null, properties: PropertyDescriptorMap): any;
|
||||
create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
|
||||
|
||||
/**
|
||||
* Adds a property to an object, or modifies attributes of an existing property.
|
||||
@@ -155,14 +155,14 @@ interface ObjectConstructor {
|
||||
* @param p The property name.
|
||||
* @param attributes Descriptor for the property. It can be for a data property or an accessor property.
|
||||
*/
|
||||
defineProperty(o: any, p: string, attributes: PropertyDescriptor): any;
|
||||
defineProperty(o: any, p: string, attributes: PropertyDescriptor & ThisType<any>): any;
|
||||
|
||||
/**
|
||||
* Adds one or more properties to an object, and/or modifies attributes of existing properties.
|
||||
* @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object.
|
||||
* @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property.
|
||||
*/
|
||||
defineProperties(o: any, properties: PropertyDescriptorMap): any;
|
||||
defineProperties(o: any, properties: PropertyDescriptorMap & ThisType<any>): any;
|
||||
|
||||
/**
|
||||
* Prevents the modification of attributes of existing properties, and prevents the addition of new properties.
|
||||
@@ -1366,6 +1366,11 @@ type Record<K extends string, T> = {
|
||||
[P in K]: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marker for contextual 'this' type
|
||||
*/
|
||||
interface ThisType<T> { }
|
||||
|
||||
/**
|
||||
* Represents a raw buffer of binary data, which is used to store data for the
|
||||
* different typed arrays. ArrayBuffers cannot be read from or written to directly,
|
||||
|
||||
Reference in New Issue
Block a user