|
|
|
|
@@ -327,10 +327,6 @@ namespace ts {
|
|
|
|
|
/** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
|
|
|
|
|
let apparentArgumentCount: number | undefined;
|
|
|
|
|
|
|
|
|
|
// This object is reused for `checkOptionalExpression` return values to avoid frequent GC due to nursery object allocations.
|
|
|
|
|
// This object represents a pool-size of 1.
|
|
|
|
|
const pooledOptionalTypeResult: { isOptional: boolean, type: Type } = { isOptional: false, type: undefined! };
|
|
|
|
|
|
|
|
|
|
// for public members that accept a Node or one of its subtypes, we must guard against
|
|
|
|
|
// synthetic nodes created during transformations by calling `getParseTreeNode`.
|
|
|
|
|
// for most of these, we perform the guard only on `checker` to avoid any possible
|
|
|
|
|
@@ -712,10 +708,10 @@ namespace ts {
|
|
|
|
|
|
|
|
|
|
const noTypePredicate = createTypePredicate(TypePredicateKind.Identifier, "<<unresolved>>", 0, anyType);
|
|
|
|
|
|
|
|
|
|
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
|
|
|
|
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
|
|
|
|
const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
|
|
|
|
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
|
|
|
|
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
|
|
|
|
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
|
|
|
|
const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
|
|
|
|
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
|
|
|
|
|
|
|
|
|
const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
|
|
|
|
|
|
|
|
|
|
@@ -7721,7 +7717,7 @@ namespace ts {
|
|
|
|
|
const signatures = getSignaturesOfType(type, SignatureKind.Construct);
|
|
|
|
|
if (signatures.length === 1) {
|
|
|
|
|
const s = signatures[0];
|
|
|
|
|
return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getElementTypeOfArrayType(getTypeOfParameter(s.parameters[0])) === anyType;
|
|
|
|
|
return !s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s) && getElementTypeOfArrayType(getTypeOfParameter(s.parameters[0])) === anyType;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
@@ -8612,10 +8608,9 @@ namespace ts {
|
|
|
|
|
resolvedReturnType: Type | undefined,
|
|
|
|
|
resolvedTypePredicate: TypePredicate | undefined,
|
|
|
|
|
minArgumentCount: number,
|
|
|
|
|
hasRestParameter: boolean,
|
|
|
|
|
hasLiteralTypes: boolean,
|
|
|
|
|
flags: SignatureFlags
|
|
|
|
|
): Signature {
|
|
|
|
|
const sig = new Signature(checker);
|
|
|
|
|
const sig = new Signature(checker, flags);
|
|
|
|
|
sig.declaration = declaration;
|
|
|
|
|
sig.typeParameters = typeParameters;
|
|
|
|
|
sig.parameters = parameters;
|
|
|
|
|
@@ -8623,8 +8618,6 @@ namespace ts {
|
|
|
|
|
sig.resolvedReturnType = resolvedReturnType;
|
|
|
|
|
sig.resolvedTypePredicate = resolvedTypePredicate;
|
|
|
|
|
sig.minArgumentCount = minArgumentCount;
|
|
|
|
|
sig.hasRestParameter = hasRestParameter;
|
|
|
|
|
sig.hasLiteralTypes = hasLiteralTypes;
|
|
|
|
|
sig.target = undefined;
|
|
|
|
|
sig.mapper = undefined;
|
|
|
|
|
return sig;
|
|
|
|
|
@@ -8632,7 +8625,7 @@ namespace ts {
|
|
|
|
|
|
|
|
|
|
function cloneSignature(sig: Signature): Signature {
|
|
|
|
|
const result = createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined,
|
|
|
|
|
/*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
|
|
|
|
|
/*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags);
|
|
|
|
|
result.target = sig.target;
|
|
|
|
|
result.mapper = sig.mapper;
|
|
|
|
|
return result;
|
|
|
|
|
@@ -8646,14 +8639,19 @@ namespace ts {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getOptionalCallSignature(signature: Signature) {
|
|
|
|
|
return signatureIsOptionalCall(signature) ? signature :
|
|
|
|
|
(signature.optionalCallSignatureCache || (signature.optionalCallSignatureCache = createOptionalCallSignature(signature)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createOptionalCallSignature(signature: Signature) {
|
|
|
|
|
const result = cloneSignature(signature);
|
|
|
|
|
result.isOptionalCall = true;
|
|
|
|
|
result.flags |= SignatureFlags.IsOptionalCall;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getExpandedParameters(sig: Signature): readonly Symbol[] {
|
|
|
|
|
if (sig.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(sig)) {
|
|
|
|
|
const restIndex = sig.parameters.length - 1;
|
|
|
|
|
const restParameter = sig.parameters[restIndex];
|
|
|
|
|
const restType = getTypeOfSymbol(restParameter);
|
|
|
|
|
@@ -8679,7 +8677,7 @@ namespace ts {
|
|
|
|
|
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
|
|
|
|
|
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
|
|
|
|
|
if (baseSignatures.length === 0) {
|
|
|
|
|
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
|
|
|
|
|
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None)];
|
|
|
|
|
}
|
|
|
|
|
const baseTypeNode = getBaseTypeNodeOfClass(classType)!;
|
|
|
|
|
const isJavaScript = isInJSFile(baseTypeNode);
|
|
|
|
|
@@ -8843,8 +8841,6 @@ namespace ts {
|
|
|
|
|
const params = combineUnionParameters(left, right);
|
|
|
|
|
const thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter);
|
|
|
|
|
const minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount);
|
|
|
|
|
const hasRestParam = left.hasRestParameter || right.hasRestParameter;
|
|
|
|
|
const hasLiteralTypes = left.hasLiteralTypes || right.hasLiteralTypes;
|
|
|
|
|
const result = createSignature(
|
|
|
|
|
declaration,
|
|
|
|
|
left.typeParameters || right.typeParameters,
|
|
|
|
|
@@ -8853,8 +8849,7 @@ namespace ts {
|
|
|
|
|
/*resolvedReturnType*/ undefined,
|
|
|
|
|
/*resolvedTypePredicate*/ undefined,
|
|
|
|
|
minArgCount,
|
|
|
|
|
hasRestParam,
|
|
|
|
|
hasLiteralTypes
|
|
|
|
|
(left.flags | right.flags) & SignatureFlags.PropagatingFlags
|
|
|
|
|
);
|
|
|
|
|
result.unionSignatures = concatenate(left.unionSignatures || [left], [right]);
|
|
|
|
|
return result;
|
|
|
|
|
@@ -9036,7 +9031,7 @@ namespace ts {
|
|
|
|
|
constructSignatures = addRange(constructSignatures.slice(), mapDefined(
|
|
|
|
|
type.callSignatures,
|
|
|
|
|
sig => isJSConstructor(sig.declaration) ?
|
|
|
|
|
createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes) :
|
|
|
|
|
createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags) :
|
|
|
|
|
undefined));
|
|
|
|
|
}
|
|
|
|
|
if (!constructSignatures.length) {
|
|
|
|
|
@@ -10043,7 +10038,7 @@ namespace ts {
|
|
|
|
|
const links = getNodeLinks(declaration);
|
|
|
|
|
if (!links.resolvedSignature) {
|
|
|
|
|
const parameters: Symbol[] = [];
|
|
|
|
|
let hasLiteralTypes = false;
|
|
|
|
|
let flags = SignatureFlags.None;
|
|
|
|
|
let minArgumentCount = 0;
|
|
|
|
|
let thisParameter: Symbol | undefined;
|
|
|
|
|
let hasThisParameter = false;
|
|
|
|
|
@@ -10077,7 +10072,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type && type.kind === SyntaxKind.LiteralType) {
|
|
|
|
|
hasLiteralTypes = true;
|
|
|
|
|
flags |= SignatureFlags.HasLiteralTypes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Record a new minimum argument count if this is not an optional parameter
|
|
|
|
|
@@ -10106,10 +10101,12 @@ namespace ts {
|
|
|
|
|
getDeclaredTypeOfClassOrInterface(getMergedSymbol((<ClassDeclaration>declaration.parent).symbol))
|
|
|
|
|
: undefined;
|
|
|
|
|
const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
|
|
|
|
|
const hasRestLikeParameter = hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters);
|
|
|
|
|
if (hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) {
|
|
|
|
|
flags |= SignatureFlags.HasRestParameter;
|
|
|
|
|
}
|
|
|
|
|
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters,
|
|
|
|
|
/*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined,
|
|
|
|
|
minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
|
|
|
|
|
minArgumentCount, flags);
|
|
|
|
|
}
|
|
|
|
|
return links.resolvedSignature;
|
|
|
|
|
}
|
|
|
|
|
@@ -10264,8 +10261,8 @@ namespace ts {
|
|
|
|
|
signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) :
|
|
|
|
|
getReturnTypeFromAnnotation(signature.declaration!) ||
|
|
|
|
|
(nodeIsMissing((<FunctionLikeDeclaration>signature.declaration).body) ? anyType : getReturnTypeFromBody(<FunctionLikeDeclaration>signature.declaration));
|
|
|
|
|
if (signature.isOptionalCall) {
|
|
|
|
|
type = propagateOptionalTypeMarker(type, /*wasOptional*/ true);
|
|
|
|
|
if (signatureIsOptionalCall(signature)) {
|
|
|
|
|
type = addOptionalTypeMarker(type);
|
|
|
|
|
}
|
|
|
|
|
if (!popTypeResolution()) {
|
|
|
|
|
if (signature.declaration) {
|
|
|
|
|
@@ -10325,7 +10322,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tryGetRestTypeOfSignature(signature: Signature): Type | undefined {
|
|
|
|
|
if (signature.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(signature)) {
|
|
|
|
|
const sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
|
|
|
|
const restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType;
|
|
|
|
|
return restType && getIndexTypeOfType(restType, IndexKind.Number);
|
|
|
|
|
@@ -12907,8 +12904,7 @@ namespace ts {
|
|
|
|
|
/*resolvedReturnType*/ undefined,
|
|
|
|
|
/*resolvedTypePredicate*/ undefined,
|
|
|
|
|
signature.minArgumentCount,
|
|
|
|
|
signature.hasRestParameter,
|
|
|
|
|
signature.hasLiteralTypes);
|
|
|
|
|
signature.flags & SignatureFlags.PropagatingFlags);
|
|
|
|
|
result.target = signature;
|
|
|
|
|
result.mapper = mapper;
|
|
|
|
|
return result;
|
|
|
|
|
@@ -13861,7 +13857,7 @@ namespace ts {
|
|
|
|
|
*/
|
|
|
|
|
function isAnySignature(s: Signature) {
|
|
|
|
|
return !s.typeParameters && (!s.thisParameter || isTypeAny(getTypeOfParameter(s.thisParameter))) && s.parameters.length === 1 &&
|
|
|
|
|
s.hasRestParameter && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
|
|
|
|
|
signatureHasRestParameter(s) && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
|
|
|
|
|
isTypeAny(getReturnTypeOfSignature(s));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -16686,48 +16682,22 @@ namespace ts {
|
|
|
|
|
return strictNullChecks ? getUnionType([type, optionalType]) : type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isNotOptionalTypeMarker(type: Type) {
|
|
|
|
|
return type !== optionalType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function removeOptionalTypeMarker(type: Type): Type {
|
|
|
|
|
return strictNullChecks ? filterType(type, t => t !== optionalType) : type;
|
|
|
|
|
return strictNullChecks ? filterType(type, isNotOptionalTypeMarker) : type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function propagateOptionalTypeMarker(type: Type, wasOptional: boolean) {
|
|
|
|
|
return wasOptional ? addOptionalTypeMarker(type) : type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createPooledOptionalTypeResult(isOptional: boolean, type: Type) {
|
|
|
|
|
pooledOptionalTypeResult.isOptional = isOptional;
|
|
|
|
|
pooledOptionalTypeResult.type = type;
|
|
|
|
|
return pooledOptionalTypeResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkOptionalExpression(
|
|
|
|
|
parent: PropertyAccessExpression | QualifiedName | ElementAccessExpression | CallExpression,
|
|
|
|
|
expression: Expression | QualifiedName,
|
|
|
|
|
nullDiagnostic?: DiagnosticMessage,
|
|
|
|
|
undefinedDiagnostic?: DiagnosticMessage,
|
|
|
|
|
nullOrUndefinedDiagnostic?: DiagnosticMessage,
|
|
|
|
|
) {
|
|
|
|
|
let isOptional = false;
|
|
|
|
|
let type = checkExpression(expression);
|
|
|
|
|
if (isOptionalChain(parent)) {
|
|
|
|
|
if (parent.questionDotToken) {
|
|
|
|
|
// If we have a questionDotToken then we are an OptionalExpression and should remove `null` and
|
|
|
|
|
// `undefined` from the type and add the optionalType to the result, if needed.
|
|
|
|
|
isOptional = isNullableType(type);
|
|
|
|
|
return createPooledOptionalTypeResult(isOptional, isOptional ? getNonNullableType(type) : type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we do not have a questionDotToken, then we are an OptionalChain and we remove the optionalType and
|
|
|
|
|
// indicate whether we need to add optionalType back into the result.
|
|
|
|
|
const nonOptionalType = removeOptionalTypeMarker(type);
|
|
|
|
|
if (nonOptionalType !== type) {
|
|
|
|
|
isOptional = true;
|
|
|
|
|
type = nonOptionalType;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type = checkNonNullType(type, expression, nullDiagnostic, undefinedDiagnostic, nullOrUndefinedDiagnostic);
|
|
|
|
|
return createPooledOptionalTypeResult(isOptional, type);
|
|
|
|
|
function getOptionalExpressionType(exprType: Type, expression: Expression) {
|
|
|
|
|
return isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType) :
|
|
|
|
|
isOptionalChain(expression) ? removeOptionalTypeMarker(exprType) :
|
|
|
|
|
exprType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -18771,9 +18741,21 @@ namespace ts {
|
|
|
|
|
// expressions are potential type predicate function calls. In order to avoid triggering
|
|
|
|
|
// circularities in control flow analysis, we use getTypeOfDottedName when resolving the call
|
|
|
|
|
// target expression of an assertion.
|
|
|
|
|
const funcType = node.parent.kind === SyntaxKind.ExpressionStatement ? getTypeOfDottedName(node.expression, /*diagnostic*/ undefined) :
|
|
|
|
|
node.expression.kind !== SyntaxKind.SuperKeyword ? checkOptionalExpression(node, node.expression).type :
|
|
|
|
|
undefined;
|
|
|
|
|
let funcType: Type | undefined;
|
|
|
|
|
if (node.parent.kind === SyntaxKind.ExpressionStatement) {
|
|
|
|
|
funcType = getTypeOfDottedName(node.expression, /*diagnostic*/ undefined);
|
|
|
|
|
}
|
|
|
|
|
else if (node.expression.kind !== SyntaxKind.SuperKeyword) {
|
|
|
|
|
if (isOptionalChain(node)) {
|
|
|
|
|
funcType = checkNonNullType(
|
|
|
|
|
getOptionalExpressionType(checkExpression(node.expression), node.expression),
|
|
|
|
|
node.expression
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
funcType = checkNonNullExpression(node.expression);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, SignatureKind.Call);
|
|
|
|
|
const candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] :
|
|
|
|
|
some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) :
|
|
|
|
|
@@ -19780,7 +19762,7 @@ namespace ts {
|
|
|
|
|
// will be a subtype or the same type as the argument.
|
|
|
|
|
function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type {
|
|
|
|
|
// for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a`
|
|
|
|
|
if (isOptionalChainRoot(expr.parent) ||
|
|
|
|
|
if (isExpressionOfOptionalChainRoot(expr) ||
|
|
|
|
|
isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === SyntaxKind.QuestionQuestionToken && expr.parent.left === expr) {
|
|
|
|
|
return narrowTypeByOptionality(type, expr, assumeTrue);
|
|
|
|
|
}
|
|
|
|
|
@@ -22682,19 +22664,8 @@ namespace ts {
|
|
|
|
|
return !!forEachProperty(symbol, prop => !(prop.flags & SymbolFlags.Method));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNonNullExpression(
|
|
|
|
|
node: Expression | QualifiedName,
|
|
|
|
|
nullDiagnostic?: DiagnosticMessage,
|
|
|
|
|
undefinedDiagnostic?: DiagnosticMessage,
|
|
|
|
|
nullOrUndefinedDiagnostic?: DiagnosticMessage,
|
|
|
|
|
) {
|
|
|
|
|
return checkNonNullType(
|
|
|
|
|
checkExpression(node),
|
|
|
|
|
node,
|
|
|
|
|
nullDiagnostic,
|
|
|
|
|
undefinedDiagnostic,
|
|
|
|
|
nullOrUndefinedDiagnostic
|
|
|
|
|
);
|
|
|
|
|
function checkNonNullExpression(node: Expression | QualifiedName) {
|
|
|
|
|
return checkNonNullType(checkExpression(node), node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isNullableType(type: Type) {
|
|
|
|
|
@@ -22705,12 +22676,26 @@ namespace ts {
|
|
|
|
|
return isNullableType(type) ? getNonNullableType(type) : type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNonNullType(
|
|
|
|
|
function reportObjectPossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) {
|
|
|
|
|
error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ?
|
|
|
|
|
Diagnostics.Object_is_possibly_null_or_undefined :
|
|
|
|
|
Diagnostics.Object_is_possibly_undefined :
|
|
|
|
|
Diagnostics.Object_is_possibly_null
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, flags: TypeFlags) {
|
|
|
|
|
error(node, flags & TypeFlags.Undefined ? flags & TypeFlags.Null ?
|
|
|
|
|
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined :
|
|
|
|
|
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined :
|
|
|
|
|
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNonNullTypeWithReporter(
|
|
|
|
|
type: Type,
|
|
|
|
|
node: Node,
|
|
|
|
|
nullDiagnostic?: DiagnosticMessage,
|
|
|
|
|
undefinedDiagnostic?: DiagnosticMessage,
|
|
|
|
|
nullOrUndefinedDiagnostic?: DiagnosticMessage
|
|
|
|
|
reportError: (node: Node, kind: TypeFlags) => void
|
|
|
|
|
): Type {
|
|
|
|
|
if (strictNullChecks && type.flags & TypeFlags.Unknown) {
|
|
|
|
|
error(node, Diagnostics.Object_is_of_type_unknown);
|
|
|
|
|
@@ -22718,17 +22703,17 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable;
|
|
|
|
|
if (kind) {
|
|
|
|
|
error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ?
|
|
|
|
|
(nullOrUndefinedDiagnostic || Diagnostics.Object_is_possibly_null_or_undefined) :
|
|
|
|
|
(undefinedDiagnostic || Diagnostics.Object_is_possibly_undefined) :
|
|
|
|
|
(nullDiagnostic || Diagnostics.Object_is_possibly_null)
|
|
|
|
|
);
|
|
|
|
|
reportError(node, kind);
|
|
|
|
|
const t = getNonNullableType(type);
|
|
|
|
|
return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? errorType : t;
|
|
|
|
|
}
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNonNullType(type: Type, node: Node) {
|
|
|
|
|
return checkNonNullTypeWithReporter(type, node, reportObjectPossiblyNullOrUndefinedError);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkNonNullNonVoidType(type: Type, node: Node): Type {
|
|
|
|
|
const nonNullType = checkNonNullType(type, node);
|
|
|
|
|
if (nonNullType !== errorType && nonNullType.flags & TypeFlags.Void) {
|
|
|
|
|
@@ -22738,11 +22723,18 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkPropertyAccessExpression(node: PropertyAccessExpression) {
|
|
|
|
|
return checkPropertyAccessExpressionOrQualifiedName(node, node.expression, node.name);
|
|
|
|
|
return node.flags & NodeFlags.OptionalChain ? checkPropertyAccessChain(node as PropertyAccessChain) :
|
|
|
|
|
checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullExpression(node.expression), node.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkPropertyAccessChain(node: PropertyAccessChain) {
|
|
|
|
|
const leftType = checkExpression(node.expression);
|
|
|
|
|
const nonOptionalType = getOptionalExpressionType(leftType, node.expression);
|
|
|
|
|
return propagateOptionalTypeMarker(checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullType(nonOptionalType, node.expression), node.name), nonOptionalType !== leftType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkQualifiedName(node: QualifiedName) {
|
|
|
|
|
return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right);
|
|
|
|
|
return checkPropertyAccessExpressionOrQualifiedName(node, node.left, checkNonNullExpression(node.left), node.right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isMethodAccessForCall(node: Node) {
|
|
|
|
|
@@ -22752,8 +22744,7 @@ namespace ts {
|
|
|
|
|
return isCallOrNewExpression(node.parent) && node.parent.expression === node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, right: Identifier) {
|
|
|
|
|
const { isOptional, type: leftType } = checkOptionalExpression(node, left);
|
|
|
|
|
function checkPropertyAccessExpressionOrQualifiedName(node: PropertyAccessExpression | QualifiedName, left: Expression | QualifiedName, leftType: Type, right: Identifier) {
|
|
|
|
|
const parentSymbol = getNodeLinks(left).resolvedSymbol;
|
|
|
|
|
const assignmentKind = getAssignmentTargetKind(node);
|
|
|
|
|
const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType);
|
|
|
|
|
@@ -22807,7 +22798,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
|
|
|
|
|
}
|
|
|
|
|
return propagateOptionalTypeMarker(getFlowTypeOfAccessExpression(node, prop, propType, right), isOptional);
|
|
|
|
|
return getFlowTypeOfAccessExpression(node, prop, propType, right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getFlowTypeOfAccessExpression(node: ElementAccessExpression | PropertyAccessExpression | QualifiedName, prop: Symbol | undefined, propType: Type, errorNode: Node) {
|
|
|
|
|
@@ -23164,7 +23155,17 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkIndexedAccess(node: ElementAccessExpression): Type {
|
|
|
|
|
const { isOptional, type: exprType } = checkOptionalExpression(node, node.expression);
|
|
|
|
|
return node.flags & NodeFlags.OptionalChain ? checkElementAccessChain(node as ElementAccessChain) :
|
|
|
|
|
checkElementAccessExpression(node, checkNonNullExpression(node.expression));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkElementAccessChain(node: ElementAccessChain) {
|
|
|
|
|
const exprType = checkExpression(node.expression);
|
|
|
|
|
const nonOptionalType = getOptionalExpressionType(exprType, node.expression);
|
|
|
|
|
return propagateOptionalTypeMarker(checkElementAccessExpression(node, checkNonNullType(nonOptionalType, node.expression)), nonOptionalType !== exprType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkElementAccessExpression(node: ElementAccessExpression, exprType: Type): Type {
|
|
|
|
|
const objectType = getAssignmentTargetKind(node) !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(exprType) : exprType;
|
|
|
|
|
const indexExpression = node.argumentExpression;
|
|
|
|
|
const indexType = checkExpression(indexExpression);
|
|
|
|
|
@@ -23183,7 +23184,7 @@ namespace ts {
|
|
|
|
|
AccessFlags.Writing | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? AccessFlags.NoIndexSignatures : 0) :
|
|
|
|
|
AccessFlags.None;
|
|
|
|
|
const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
|
|
|
|
|
return propagateOptionalTypeMarker(checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node), isOptional);
|
|
|
|
|
return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function checkThatExpressionIsProperSymbolReference(expression: Expression, expressionType: Type, reportError: boolean): boolean {
|
|
|
|
|
@@ -23296,7 +23297,7 @@ namespace ts {
|
|
|
|
|
|
|
|
|
|
// specialized signatures always need to be placed before non-specialized signatures regardless
|
|
|
|
|
// of the cutoff position; see GH#1133
|
|
|
|
|
if (signature.hasLiteralTypes) {
|
|
|
|
|
if (signatureHasLiteralTypes(signature)) {
|
|
|
|
|
specializedIndex++;
|
|
|
|
|
spliceIndex = specializedIndex;
|
|
|
|
|
// The cutoff index always needs to be greater than or equal to the specialized signature index
|
|
|
|
|
@@ -23308,7 +23309,7 @@ namespace ts {
|
|
|
|
|
spliceIndex = index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.splice(spliceIndex, 0, isOptionalCall ? createOptionalCallSignature(signature) : signature);
|
|
|
|
|
result.splice(spliceIndex, 0, isOptionalCall ? getOptionalCallSignature(signature) : signature);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -24266,17 +24267,21 @@ namespace ts {
|
|
|
|
|
const { min: minArgumentCount, max: maxNonRestParam } = minAndMax(candidates, getNumNonRestParameters);
|
|
|
|
|
const parameters: Symbol[] = [];
|
|
|
|
|
for (let i = 0; i < maxNonRestParam; i++) {
|
|
|
|
|
const symbols = mapDefined(candidates, ({ parameters, hasRestParameter }) => hasRestParameter ?
|
|
|
|
|
i < parameters.length - 1 ? parameters[i] : last(parameters) :
|
|
|
|
|
i < parameters.length ? parameters[i] : undefined);
|
|
|
|
|
const symbols = mapDefined(candidates, s => signatureHasRestParameter(s) ?
|
|
|
|
|
i < s.parameters.length - 1 ? s.parameters[i] : last(s.parameters) :
|
|
|
|
|
i < s.parameters.length ? s.parameters[i] : undefined);
|
|
|
|
|
Debug.assert(symbols.length !== 0);
|
|
|
|
|
parameters.push(createCombinedSymbolFromTypes(symbols, mapDefined(candidates, candidate => tryGetTypeAtPosition(candidate, i))));
|
|
|
|
|
}
|
|
|
|
|
const restParameterSymbols = mapDefined(candidates, c => c.hasRestParameter ? last(c.parameters) : undefined);
|
|
|
|
|
const hasRestParameter = restParameterSymbols.length !== 0;
|
|
|
|
|
if (hasRestParameter) {
|
|
|
|
|
const restParameterSymbols = mapDefined(candidates, c => signatureHasRestParameter(c) ? last(c.parameters) : undefined);
|
|
|
|
|
let flags = SignatureFlags.None;
|
|
|
|
|
if (restParameterSymbols.length !== 0) {
|
|
|
|
|
const type = createArrayType(getUnionType(mapDefined(candidates, tryGetRestTypeOfSignature), UnionReduction.Subtype));
|
|
|
|
|
parameters.push(createCombinedSymbolForOverloadFailure(restParameterSymbols, type));
|
|
|
|
|
flags |= SignatureFlags.HasRestParameter;
|
|
|
|
|
}
|
|
|
|
|
if (candidates.some(signatureHasLiteralTypes)) {
|
|
|
|
|
flags |= SignatureFlags.HasLiteralTypes;
|
|
|
|
|
}
|
|
|
|
|
return createSignature(
|
|
|
|
|
candidates[0].declaration,
|
|
|
|
|
@@ -24286,13 +24291,12 @@ namespace ts {
|
|
|
|
|
/*resolvedReturnType*/ getIntersectionType(candidates.map(getReturnTypeOfSignature)),
|
|
|
|
|
/*typePredicate*/ undefined,
|
|
|
|
|
minArgumentCount,
|
|
|
|
|
hasRestParameter,
|
|
|
|
|
/*hasLiteralTypes*/ candidates.some(c => c.hasLiteralTypes));
|
|
|
|
|
flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getNumNonRestParameters(signature: Signature): number {
|
|
|
|
|
const numParams = signature.parameters.length;
|
|
|
|
|
return signature.hasRestParameter ? numParams - 1 : numParams;
|
|
|
|
|
return signatureHasRestParameter(signature) ? numParams - 1 : numParams;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createCombinedSymbolFromTypes(sources: readonly Symbol[], types: Type[]): Symbol {
|
|
|
|
|
@@ -24383,12 +24387,20 @@ namespace ts {
|
|
|
|
|
return resolveUntypedCall(node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { isOptional, type: funcType } = checkOptionalExpression(
|
|
|
|
|
node,
|
|
|
|
|
let isOptional: boolean;
|
|
|
|
|
let funcType = checkExpression(node.expression);
|
|
|
|
|
if (isCallChain(node)) {
|
|
|
|
|
const nonOptionalType = getOptionalExpressionType(funcType, node.expression);
|
|
|
|
|
isOptional = nonOptionalType !== funcType;
|
|
|
|
|
funcType = nonOptionalType;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
isOptional = false;
|
|
|
|
|
}
|
|
|
|
|
funcType = checkNonNullTypeWithReporter(
|
|
|
|
|
funcType,
|
|
|
|
|
node.expression,
|
|
|
|
|
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null,
|
|
|
|
|
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined,
|
|
|
|
|
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined
|
|
|
|
|
reportCannotInvokePossiblyNullOrUndefinedError
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (funcType === silentNeverType) {
|
|
|
|
|
@@ -24842,8 +24854,7 @@ namespace ts {
|
|
|
|
|
typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType,
|
|
|
|
|
/*returnTypePredicate*/ undefined,
|
|
|
|
|
1,
|
|
|
|
|
/*hasRestparameter*/ false,
|
|
|
|
|
/*hasLiteralTypes*/ false
|
|
|
|
|
SignatureFlags.None
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -24882,7 +24893,7 @@ namespace ts {
|
|
|
|
|
function isPotentiallyUncalledDecorator(decorator: Decorator, signatures: readonly Signature[]) {
|
|
|
|
|
return signatures.length && every(signatures, signature =>
|
|
|
|
|
signature.minArgumentCount === 0 &&
|
|
|
|
|
!signature.hasRestParameter &&
|
|
|
|
|
!signatureHasRestParameter(signature) &&
|
|
|
|
|
signature.parameters.length < getDecoratorArgumentCount(decorator, signature));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -25298,7 +25309,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getParameterNameAtPosition(signature: Signature, pos: number) {
|
|
|
|
|
const paramCount = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
|
|
|
|
const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
|
|
|
|
if (pos < paramCount) {
|
|
|
|
|
return signature.parameters[pos].escapedName;
|
|
|
|
|
}
|
|
|
|
|
@@ -25317,11 +25328,11 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tryGetTypeAtPosition(signature: Signature, pos: number): Type | undefined {
|
|
|
|
|
const paramCount = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
|
|
|
|
const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
|
|
|
|
if (pos < paramCount) {
|
|
|
|
|
return getTypeOfParameter(signature.parameters[pos]);
|
|
|
|
|
}
|
|
|
|
|
if (signature.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(signature)) {
|
|
|
|
|
// We want to return the value undefined for an out of bounds parameter position,
|
|
|
|
|
// so we need to check bounds here before calling getIndexedAccessType (which
|
|
|
|
|
// otherwise would return the type 'undefined').
|
|
|
|
|
@@ -25358,7 +25369,7 @@ namespace ts {
|
|
|
|
|
|
|
|
|
|
function getParameterCount(signature: Signature) {
|
|
|
|
|
const length = signature.parameters.length;
|
|
|
|
|
if (signature.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(signature)) {
|
|
|
|
|
const restType = getTypeOfSymbol(signature.parameters[length - 1]);
|
|
|
|
|
if (isTupleType(restType)) {
|
|
|
|
|
return length + getTypeArguments(restType).length - 1;
|
|
|
|
|
@@ -25368,7 +25379,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getMinArgumentCount(signature: Signature) {
|
|
|
|
|
if (signature.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(signature)) {
|
|
|
|
|
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
|
|
|
|
if (isTupleType(restType)) {
|
|
|
|
|
const minLength = restType.target.minLength;
|
|
|
|
|
@@ -25381,7 +25392,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hasEffectiveRestParameter(signature: Signature) {
|
|
|
|
|
if (signature.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(signature)) {
|
|
|
|
|
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
|
|
|
|
return !isTupleType(restType) || restType.target.hasRestElement;
|
|
|
|
|
}
|
|
|
|
|
@@ -25389,7 +25400,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getEffectiveRestType(signature: Signature) {
|
|
|
|
|
if (signature.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(signature)) {
|
|
|
|
|
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
|
|
|
|
return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType;
|
|
|
|
|
}
|
|
|
|
|
@@ -25410,7 +25421,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function inferFromAnnotatedParameters(signature: Signature, context: Signature, inferenceContext: InferenceContext) {
|
|
|
|
|
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
|
|
|
|
const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
|
|
|
|
for (let i = 0; i < len; i++) {
|
|
|
|
|
const declaration = <ParameterDeclaration>signature.parameters[i].valueDeclaration;
|
|
|
|
|
if (declaration.type) {
|
|
|
|
|
@@ -25444,7 +25455,7 @@ namespace ts {
|
|
|
|
|
assignTypeToParameterAndFixTypeParameters(signature.thisParameter!, getTypeOfSymbol(context.thisParameter));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0);
|
|
|
|
|
const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
|
|
|
|
|
for (let i = 0; i < len; i++) {
|
|
|
|
|
const parameter = signature.parameters[i];
|
|
|
|
|
if (!getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
|
|
|
|
|
@@ -25452,7 +25463,7 @@ namespace ts {
|
|
|
|
|
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (signature.hasRestParameter) {
|
|
|
|
|
if (signatureHasRestParameter(signature)) {
|
|
|
|
|
// parameter might be a transient symbol generated by use of `arguments` in the function body.
|
|
|
|
|
const parameter = last(signature.parameters);
|
|
|
|
|
if (isTransientSymbol(parameter) || !getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
|
|
|
|
|
@@ -25890,7 +25901,7 @@ namespace ts {
|
|
|
|
|
return links.contextFreeType;
|
|
|
|
|
}
|
|
|
|
|
const returnType = getReturnTypeFromBody(node, checkMode);
|
|
|
|
|
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
|
|
|
|
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
|
|
|
|
|
const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined);
|
|
|
|
|
returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType;
|
|
|
|
|
return links.contextFreeType = returnOnlyType;
|
|
|
|
|
@@ -27355,7 +27366,18 @@ namespace ts {
|
|
|
|
|
// Optimize for the common case of a call to a function with a single non-generic call
|
|
|
|
|
// signature where we can just fetch the return type without checking the arguments.
|
|
|
|
|
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
|
|
|
|
|
const { isOptional, type: funcType } = checkOptionalExpression(expr, expr.expression);
|
|
|
|
|
let isOptional: boolean;
|
|
|
|
|
let funcType: Type;
|
|
|
|
|
if (isCallChain(expr)) {
|
|
|
|
|
funcType = checkExpression(expr.expression);
|
|
|
|
|
const nonOptionalType = getOptionalExpressionType(funcType, expr.expression);
|
|
|
|
|
isOptional = funcType !== nonOptionalType;
|
|
|
|
|
funcType = checkNonNullType(nonOptionalType, expr.expression);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
isOptional = false;
|
|
|
|
|
funcType = checkNonNullExpression(expr.expression);
|
|
|
|
|
}
|
|
|
|
|
const signature = getSingleCallSignature(funcType);
|
|
|
|
|
if (signature && !signature.typeParameters) {
|
|
|
|
|
return propagateOptionalTypeMarker(getReturnTypeOfSignature(signature), isOptional);
|
|
|
|
|
@@ -27630,7 +27652,7 @@ namespace ts {
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (typePredicate.parameterIndex >= 0) {
|
|
|
|
|
if (signature.hasRestParameter && typePredicate.parameterIndex === signature.parameters.length - 1) {
|
|
|
|
|
if (signatureHasRestParameter(signature) && typePredicate.parameterIndex === signature.parameters.length - 1) {
|
|
|
|
|
error(parameterName, Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
@@ -36062,4 +36084,16 @@ namespace ts {
|
|
|
|
|
case IterationTypeKind.Next: return "nextType";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function signatureHasRestParameter(s: Signature) {
|
|
|
|
|
return !!(s.flags & SignatureFlags.HasRestParameter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function signatureHasLiteralTypes(s: Signature) {
|
|
|
|
|
return !!(s.flags & SignatureFlags.HasLiteralTypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function signatureIsOptionalCall(s: Signature) {
|
|
|
|
|
return !!(s.flags & SignatureFlags.IsOptionalCall);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|