Lazily compute signature type predicates (#17600)

* Lazily compute signature type predicates

* Use an instance of IdentifierTypePredicate to represent an unresolved type predicate

* Simplify `getMaybeTypePredicate`

* Invert representation of `resolvedTypePredicate`

* Remove `__unresolvedTypePredicate` type and remember to use `noTypePredicate` instead of `undefined` when in all `createSignature` calls

* Fix style of getTypePredicateOfSignature

* Use in createGetSymbolWalker

* Fix bugs for unions of type predicates

* Code review

* Make noTypePredicate purely an implementation detail of getTypePredictateOfSignature

* Add test

* Add test for #19642

* Add test with reversed order
This commit is contained in:
Andy
2017-12-05 08:32:34 -08:00
committed by GitHub
parent e42ecea8fb
commit 8153397e91
29 changed files with 1080 additions and 480 deletions
+151 -59
View File
@@ -210,7 +210,18 @@ namespace ts {
getEmitResolver,
getExportsOfModule: getExportsOfModuleAsArray,
getExportsAndPropertiesOfModule,
getSymbolWalker: createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier),
getSymbolWalker: createGetSymbolWalker(
getRestTypeOfSignature,
getTypePredicateOfSignature,
getReturnTypeOfSignature,
getBaseTypes,
resolveStructuredTypeMembers,
getTypeOfSymbol,
getResolvedSymbol,
getIndexTypeOfStructuredType,
getConstraintFromTypeParameter,
getFirstIdentifier,
),
getAmbientModules,
getAllAttributesTypeFromJsxOpeningLikeElement: node => {
node = getParseTreeNode(node, isJsxOpeningLikeElement);
@@ -312,10 +323,12 @@ namespace ts {
markerSubType.constraint = markerSuperType;
const markerOtherType = <TypeParameter>createType(TypeFlags.TypeParameter);
const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
const noTypePredicate = createIdentifierTypePredicate("<<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, unknownType, /*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 enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
@@ -2926,8 +2939,8 @@ namespace ts {
parameters.unshift(thisParameter);
}
let returnTypeNode: TypeNode;
if (signature.typePredicate) {
const typePredicate = signature.typePredicate;
const typePredicate = getTypePredicateOfSignature(signature);
if (typePredicate) {
const parameterName = typePredicate.kind === TypePredicateKind.Identifier ?
setEmitFlags(createIdentifier((<IdentifierTypePredicate>typePredicate).parameterName), EmitFlags.NoAsciiEscaping) :
createThisTypeNode();
@@ -3887,8 +3900,9 @@ namespace ts {
}
writeSpace(writer);
if (signature.typePredicate) {
buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack);
const typePredicate = getTypePredicateOfSignature(signature);
if (typePredicate) {
buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags, symbolStack);
}
else {
buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack);
@@ -5783,15 +5797,24 @@ namespace ts {
resolveObjectTypeMembers(type, source, typeParameters, typeArguments);
}
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[],
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature {
function createSignature(
declaration: SignatureDeclaration,
typeParameters: TypeParameter[],
thisParameter: Symbol | undefined,
parameters: Symbol[],
resolvedReturnType: Type | undefined,
resolvedTypePredicate: TypePredicate | undefined,
minArgumentCount: number,
hasRestParameter: boolean,
hasLiteralTypes: boolean,
): Signature {
const sig = new Signature(checker);
sig.declaration = declaration;
sig.typeParameters = typeParameters;
sig.parameters = parameters;
sig.thisParameter = thisParameter;
sig.resolvedReturnType = resolvedReturnType;
sig.typePredicate = typePredicate;
sig.resolvedTypePredicate = resolvedTypePredicate;
sig.minArgumentCount = minArgumentCount;
sig.hasRestParameter = hasRestParameter;
sig.hasLiteralTypes = hasLiteralTypes;
@@ -5799,15 +5822,15 @@ namespace ts {
}
function cloneSignature(sig: Signature): Signature {
return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType,
sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined,
/*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes);
}
function getDefaultConstructSignatures(classType: InterfaceType): Signature[] {
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct);
if (baseSignatures.length === 0) {
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)];
}
const baseTypeNode = getBaseTypeNodeOfClass(classType);
const isJavaScript = isInJavaScriptFile(baseTypeNode);
@@ -5817,7 +5840,7 @@ namespace ts {
for (const baseSig of baseSignatures) {
const minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters);
const typeParamCount = length(baseSig.typeParameters);
if (isJavaScript || (typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount)) {
if (isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) {
const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
sig.typeParameters = classType.localTypeParameters;
sig.resolvedReturnType = classType;
@@ -5877,13 +5900,13 @@ namespace ts {
let s = signature;
// Union the result types when more than one signature matches
if (unionSignatures.length > 1) {
s = cloneSignature(signature);
let thisParameter = signature.thisParameter;
if (forEach(unionSignatures, sig => sig.thisParameter)) {
const thisType = getUnionType(map(unionSignatures, sig => getTypeOfSymbol(sig.thisParameter) || anyType), /*subtypeReduction*/ true);
s.thisParameter = createSymbolWithType(signature.thisParameter, thisType);
thisParameter = createSymbolWithType(signature.thisParameter, thisType);
}
// Clear resolved return type we possibly got from cloneSignature
s.resolvedReturnType = undefined;
s = cloneSignature(signature);
s.thisParameter = thisParameter;
s.unionSignatures = unionSignatures;
}
(result || (result = [])).push(s);
@@ -6434,14 +6457,13 @@ namespace ts {
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol {
let props: Symbol[];
const types = containingType.types;
const isUnion = containingType.flags & TypeFlags.Union;
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
// Flags we want to propagate to the result if they exist in all source symbols
let commonFlags = isUnion ? SymbolFlags.None : SymbolFlags.Optional;
let syntheticFlag = CheckFlags.SyntheticMethod;
let checkFlags = 0;
for (const current of types) {
for (const current of containingType.types) {
const type = getApparentType(current);
if (type !== unknownType) {
const prop = getPropertyOfType(type, name);
@@ -6674,22 +6696,26 @@ namespace ts {
function createTypePredicateFromTypePredicateNode(node: TypePredicateNode): IdentifierTypePredicate | ThisTypePredicate {
const { parameterName } = node;
const type = getTypeFromTypeNode(node.type);
if (parameterName.kind === SyntaxKind.Identifier) {
return {
kind: TypePredicateKind.Identifier,
parameterName: parameterName ? parameterName.escapedText : undefined,
parameterIndex: parameterName ? getTypePredicateParameterIndex((node.parent as SignatureDeclaration).parameters, parameterName) : undefined,
type: getTypeFromTypeNode(node.type)
} as IdentifierTypePredicate;
return createIdentifierTypePredicate(
parameterName && parameterName.escapedText as string, // TODO: GH#18217
parameterName && getTypePredicateParameterIndex((node.parent as SignatureDeclaration).parameters, parameterName),
type);
}
else {
return {
kind: TypePredicateKind.This,
type: getTypeFromTypeNode(node.type)
};
return createThisTypePredicate(type);
}
}
function createIdentifierTypePredicate(parameterName: string | undefined, parameterIndex: number | undefined, type: Type): IdentifierTypePredicate {
return { kind: TypePredicateKind.Identifier, parameterName, parameterIndex, type };
}
function createThisTypePredicate(type: Type): ThisTypePredicate {
return { kind: TypePredicateKind.This, type };
}
/**
* Gets the minimum number of type arguments needed to satisfy all non-optional type
* parameters.
@@ -6805,11 +6831,8 @@ namespace ts {
: undefined;
const typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
const returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType);
const typePredicate = declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
undefined;
const hasRestLikeParameter = hasRestParameter(declaration) || isInJavaScriptFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters);
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, /*resolvedTypePredicate*/ undefined, minArgumentCount, hasRestLikeParameter, hasLiteralTypes);
}
return links.resolvedSignature;
}
@@ -6946,6 +6969,30 @@ namespace ts {
}
}
function signatureHasTypePredicate(signature: Signature): boolean {
return getTypePredicateOfSignature(signature) !== undefined;
}
function getTypePredicateOfSignature(signature: Signature): TypePredicate | undefined {
if (!signature.resolvedTypePredicate) {
if (signature.target) {
const targetTypePredicate = getTypePredicateOfSignature(signature.target);
signature.resolvedTypePredicate = targetTypePredicate ? instantiateTypePredicate(targetTypePredicate, signature.mapper) : noTypePredicate;
}
else if (signature.unionSignatures) {
signature.resolvedTypePredicate = getUnionTypePredicate(signature.unionSignatures) || noTypePredicate;
}
else {
const declaration = signature.declaration;
signature.resolvedTypePredicate = declaration && declaration.type && declaration.type.kind === SyntaxKind.TypePredicate ?
createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) :
noTypePredicate;
}
Debug.assert(!!signature.resolvedTypePredicate);
}
return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate;
}
function getReturnTypeOfSignature(signature: Signature): Type {
if (!signature.resolvedReturnType) {
if (!pushTypeResolution(signature, TypeSystemPropertyName.ResolvedReturnType)) {
@@ -7824,6 +7871,42 @@ namespace ts {
return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
}
function getUnionTypePredicate(signatures: ReadonlyArray<Signature>): TypePredicate {
let first: TypePredicate | undefined;
const types: Type[] = [];
for (const sig of signatures) {
const pred = getTypePredicateOfSignature(sig);
if (!pred) {
continue;
}
if (first) {
if (!typePredicateKindsMatch(first, pred)) {
// No common type predicate.
return undefined;
}
}
else {
first = pred;
}
types.push(pred.type);
}
if (!first) {
// No union signatures had a type predicate.
return undefined;
}
const unionType = getUnionType(types);
return isIdentifierTypePredicate(first)
? createIdentifierTypePredicate(first.parameterName, first.parameterIndex, unionType)
: createThisTypePredicate(unionType);
}
function typePredicateKindsMatch(a: TypePredicate, b: TypePredicate): boolean {
return isIdentifierTypePredicate(a)
? isIdentifierTypePredicate(b) && a.parameterIndex === b.parameterIndex
: !isIdentifierTypePredicate(b);
}
// This function assumes the constituent type list is sorted and deduplicated.
function getUnionTypeFromSortedList(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
if (types.length === 0) {
@@ -8574,7 +8657,7 @@ namespace ts {
return result;
}
function cloneTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate {
function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate {
if (isIdentifierTypePredicate(predicate)) {
return {
kind: TypePredicateKind.Identifier,
@@ -8593,7 +8676,6 @@ namespace ts {
function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature {
let freshTypeParameters: TypeParameter[];
let freshTypePredicate: TypePredicate;
if (signature.typeParameters && !eraseTypeParameters) {
// First create a fresh set of type parameters, then include a mapping from the old to the
// new type parameters in the mapper function. Finally store this mapper in the new type
@@ -8604,15 +8686,17 @@ namespace ts {
tp.mapper = mapper;
}
}
if (signature.typePredicate) {
freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper);
}
// Don't compute resolvedReturnType and resolvedTypePredicate now,
// because using `mapper` now could trigger inferences to become fixed. (See `createInferenceContext`.)
// See GH#17600.
const result = createSignature(signature.declaration, freshTypeParameters,
signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper),
instantiateList(signature.parameters, mapper, instantiateSymbol),
/*resolvedReturnType*/ undefined,
freshTypePredicate,
signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes);
/*resolvedTypePredicate*/ undefined,
signature.minArgumentCount,
signature.hasRestParameter,
signature.hasLiteralTypes);
result.target = signature;
result.mapper = mapper;
return result;
@@ -9006,7 +9090,7 @@ namespace ts {
// with respect to T.
const sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
const targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType));
const callbacks = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate &&
const callbacks = sourceSig && targetSig && !signatureHasTypePredicate(sourceSig) && !signatureHasTypePredicate(targetSig) &&
(getFalsyFlags(sourceType) & TypeFlags.Nullable) === (getFalsyFlags(targetType) & TypeFlags.Nullable);
const related = callbacks ?
compareSignaturesRelated(targetSig, sourceSig, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) :
@@ -9030,11 +9114,13 @@ namespace ts {
const sourceReturnType = getReturnTypeOfSignature(source);
// The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
if (target.typePredicate) {
if (source.typePredicate) {
result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes);
const targetTypePredicate = getTypePredicateOfSignature(target);
if (targetTypePredicate) {
const sourceTypePredicate = getTypePredicateOfSignature(source);
if (sourceTypePredicate) {
result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes);
}
else if (isIdentifierTypePredicate(target.typePredicate)) {
else if (isIdentifierTypePredicate(targetTypePredicate)) {
if (reportErrors) {
errorReporter(Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
}
@@ -10579,11 +10665,20 @@ namespace ts {
result &= related;
}
if (!ignoreReturnTypes) {
result &= compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
result &= sourceTypePredicate !== undefined || targetTypePredicate !== undefined
? compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes)
// If they're both type predicates their return types will both be `boolean`, so no need to compare those.
: compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
}
return result;
}
function compareTypePredicatesIdentical(source: TypePredicate | undefined, target: TypePredicate | undefined, compareTypes: (s: Type, t: Type) => Ternary): Ternary {
return source === undefined || target === undefined || !typePredicateKindsMatch(source, target) ? Ternary.False : compareTypes(source.type, target.type);
}
function isRestParameterIndex(signature: Signature, parameterIndex: number) {
return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1;
}
@@ -11448,8 +11543,10 @@ namespace ts {
function inferFromSignature(source: Signature, target: Signature) {
forEachMatchingParameterType(source, target, inferFromContravariantTypes);
if (source.typePredicate && target.typePredicate && source.typePredicate.kind === target.typePredicate.kind) {
inferFromTypes(source.typePredicate.type, target.typePredicate.type);
const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
if (sourceTypePredicate && targetTypePredicate && sourceTypePredicate.kind === targetTypePredicate.kind) {
inferFromTypes(sourceTypePredicate.type, targetTypePredicate.type);
}
else {
inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
@@ -12264,10 +12361,7 @@ namespace ts {
const funcType = checkNonNullExpression(node.expression);
if (funcType !== silentNeverType) {
const apparentType = getApparentType(funcType);
if (apparentType !== unknownType) {
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
return !!forEach(callSignatures, sig => sig.typePredicate);
}
return apparentType !== unknownType && some(getSignaturesOfType(apparentType, SignatureKind.Call), signatureHasTypePredicate);
}
}
return false;
@@ -12840,7 +12934,7 @@ namespace ts {
return type;
}
const signature = getResolvedSignature(callExpression);
const predicate = signature.typePredicate;
const predicate = getTypePredicateOfSignature(signature);
if (!predicate) {
return type;
}
@@ -14251,8 +14345,6 @@ namespace ts {
let result: Signature;
if (signatureList) {
result = cloneSignature(signatureList[0]);
// Clear resolved return type we possibly got from cloneSignature
result.resolvedReturnType = undefined;
result.unionSignatures = signatureList;
}
return result;
@@ -19305,7 +19397,7 @@ namespace ts {
return;
}
const typePredicate = getSignatureFromDeclaration(parent).typePredicate;
const typePredicate = getTypePredicateOfSignature(getSignatureFromDeclaration(parent));
if (!typePredicate) {
return;
}
+4 -2
View File
@@ -2,6 +2,7 @@
namespace ts {
export function createGetSymbolWalker(
getRestTypeOfSignature: (sig: Signature) => Type,
getTypePredicateOfSignature: (sig: Signature) => TypePredicate | undefined,
getReturnTypeOfSignature: (sig: Signature) => Type,
getBaseTypes: (type: Type) => Type[],
resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType,
@@ -117,8 +118,9 @@ namespace ts {
}
function visitSignature(signature: Signature): void {
if (signature.typePredicate) {
visitType(signature.typePredicate.type);
const typePredicate = getTypePredicateOfSignature(signature);
if (typePredicate) {
visitType(typePredicate.type);
}
forEach(signature.typeParameters, visitType);
+18 -4
View File
@@ -2791,7 +2791,17 @@ namespace ts {
/* @internal */ createPromiseType(type: Type): Type;
/* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo, numberIndexInfo: IndexInfo): Type;
/* @internal */ createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[], resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature;
/* @internal */ createSignature(
declaration: SignatureDeclaration,
typeParameters: TypeParameter[],
thisParameter: Symbol | undefined,
parameters: Symbol[],
resolvedReturnType: Type,
typePredicate: TypePredicate | undefined,
minArgumentCount: number,
hasRestParameter: boolean,
hasLiteralTypes: boolean,
): Signature;
/* @internal */ createSymbol(flags: SymbolFlags, name: __String): TransientSymbol;
/* @internal */ createIndexInfo(type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo;
/* @internal */ isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
@@ -3638,7 +3648,13 @@ namespace ts {
/* @internal */
thisParameter?: Symbol; // symbol of this-type parameter
/* @internal */
resolvedReturnType: Type; // Resolved return type
// See comment in `instantiateSignature` for why these are set lazily.
resolvedReturnType: Type | undefined; // Lazily set by `getReturnTypeOfSignature`.
/* @internal */
// Lazily set by `getTypePredicateOfSignature`.
// `undefined` indicates a type predicate that has not yet been computed.
// Uses a special `noTypePredicate` sentinel value to indicate that there is no type predicate. This looks like a TypePredicate at runtime to avoid polymorphism.
resolvedTypePredicate: TypePredicate | undefined;
/* @internal */
minArgumentCount: number; // Number of non-optional parameters
/* @internal */
@@ -3658,8 +3674,6 @@ namespace ts {
/* @internal */
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
/* @internal */
typePredicate?: TypePredicate;
/* @internal */
instantiations?: Map<Signature>; // Generic signature instantiation cache
}
+1
View File
@@ -488,6 +488,7 @@ namespace ts {
parameters: Symbol[];
thisParameter: Symbol;
resolvedReturnType: Type;
resolvedTypePredicate: TypePredicate | undefined;
minTypeArgumentCount: number;
minArgumentCount: number;
hasRestParameter: boolean;
@@ -3,72 +3,72 @@ tests/cases/conformance/fixSignatureCaching.ts(284,10): error TS2339: Property '
tests/cases/conformance/fixSignatureCaching.ts(293,10): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(294,10): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(295,10): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(327,74): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(366,10): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(384,10): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(404,10): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(405,26): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(428,10): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(429,28): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(430,31): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(440,10): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(455,10): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(456,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(457,18): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(460,10): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(461,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(464,10): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(471,23): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(471,38): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(478,22): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(478,37): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(486,18): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(487,39): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(489,37): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(492,51): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(495,52): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(498,25): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(499,48): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(508,10): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(633,10): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(634,21): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(634,36): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(635,18): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(635,33): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(638,10): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(639,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(639,38): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(640,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(641,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(704,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(734,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(783,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(805,46): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(805,61): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(828,47): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(828,64): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(845,39): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(869,25): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(890,25): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(912,36): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(912,53): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(941,33): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(952,42): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(959,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(959,42): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(960,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(961,57): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(964,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(968,18): error TS2339: Property '_impl' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(970,18): error TS2339: Property 'version' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(975,16): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(975,42): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(976,37): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(977,23): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(977,48): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(978,16): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(979,23): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(330,74): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(369,10): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(387,10): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(407,10): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(408,26): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(431,10): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(432,28): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(433,31): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(443,10): error TS2339: Property 'prepareVersionNo' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(458,10): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(459,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(460,18): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(463,10): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(464,21): error TS2339: Property 'detectMobileBrowsers' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(467,10): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(474,23): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(474,38): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(481,22): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(481,37): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(489,18): error TS2339: Property 'isMobileFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(490,39): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(492,37): error TS2339: Property 'FALLBACK_MOBILE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(495,51): error TS2339: Property 'FALLBACK_PHONE' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(498,52): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(501,25): error TS2339: Property 'isTabletFallback' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(502,48): error TS2339: Property 'FALLBACK_TABLET' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(511,10): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(636,10): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(637,21): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(637,36): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(638,18): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(638,33): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(641,10): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(642,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(642,38): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(643,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(644,13): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(707,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(737,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(786,18): error TS2339: Property 'prepareDetectionCache' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(808,46): error TS2339: Property 'findMatch' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(808,61): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(831,47): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(831,64): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(848,39): error TS2339: Property 'detectOS' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(872,25): error TS2339: Property 'getVersion' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(893,25): error TS2339: Property 'getVersionStr' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(915,36): error TS2339: Property 'findMatches' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(915,53): error TS2339: Property 'mobileDetectRules' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(944,33): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(955,42): error TS2339: Property 'mobileGrade' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(962,16): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(962,42): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(963,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(964,57): error TS2339: Property 'getDeviceSmallerSide' does not exist on type '{}'.
tests/cases/conformance/fixSignatureCaching.ts(967,22): error TS2339: Property 'isPhoneSized' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(971,18): error TS2339: Property '_impl' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(973,18): error TS2339: Property 'version' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
tests/cases/conformance/fixSignatureCaching.ts(978,16): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(978,42): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(979,37): error TS2304: Cannot find name 'module'.
tests/cases/conformance/fixSignatureCaching.ts(980,23): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(980,48): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(981,16): error TS2304: Cannot find name 'define'.
tests/cases/conformance/fixSignatureCaching.ts(982,23): error TS2304: Cannot find name 'window'.
tests/cases/conformance/fixSignatureCaching.ts(983,37): error TS2304: Cannot find name 'window'.
==== tests/cases/conformance/fixSignatureCaching.ts (71 errors) ====
@@ -380,6 +380,9 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
@@ -1164,7 +1167,7 @@ tests/cases/conformance/fixSignatureCaching.ts(980,37): error TS2304: Cannot fin
MobileDetect._impl = impl;
~~~~~
!!! error TS2339: Property '_impl' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
MobileDetect.version = '1.3.3 2016-07-31';
~~~~~~~
!!! error TS2339: Property 'version' does not exist on type '(userAgent: any, maxPhoneWidth: any) => void'.
@@ -297,6 +297,9 @@ define(function () {
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
@@ -967,7 +970,7 @@ define(function () {
// should not be replaced by a completely new object - just overwrite existing methods
MobileDetect._impl = impl;
MobileDetect.version = '1.3.3 2016-07-31';
return MobileDetect;
@@ -1276,6 +1279,9 @@ define(function () {
impl.FALLBACK_MOBILE = 'UnknownMobile';
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
//// [typeInferenceTypePredicate.ts]
declare function f<T>(predicate: (x: {}) => x is T): T;
// 'res' should be of type 'number'.
const res = f((n): n is number => true);
//// [typeInferenceTypePredicate.js]
// 'res' should be of type 'number'.
var res = f(function (n) { return true; });
@@ -0,0 +1,17 @@
=== tests/cases/compiler/typeInferenceTypePredicate.ts ===
declare function f<T>(predicate: (x: {}) => x is T): T;
>f : Symbol(f, Decl(typeInferenceTypePredicate.ts, 0, 0))
>T : Symbol(T, Decl(typeInferenceTypePredicate.ts, 0, 19))
>predicate : Symbol(predicate, Decl(typeInferenceTypePredicate.ts, 0, 22))
>x : Symbol(x, Decl(typeInferenceTypePredicate.ts, 0, 34))
>x : Symbol(x, Decl(typeInferenceTypePredicate.ts, 0, 34))
>T : Symbol(T, Decl(typeInferenceTypePredicate.ts, 0, 19))
>T : Symbol(T, Decl(typeInferenceTypePredicate.ts, 0, 19))
// 'res' should be of type 'number'.
const res = f((n): n is number => true);
>res : Symbol(res, Decl(typeInferenceTypePredicate.ts, 2, 5))
>f : Symbol(f, Decl(typeInferenceTypePredicate.ts, 0, 0))
>n : Symbol(n, Decl(typeInferenceTypePredicate.ts, 2, 15))
>n : Symbol(n, Decl(typeInferenceTypePredicate.ts, 2, 15))
@@ -0,0 +1,20 @@
=== tests/cases/compiler/typeInferenceTypePredicate.ts ===
declare function f<T>(predicate: (x: {}) => x is T): T;
>f : <T>(predicate: (x: {}) => x is T) => T
>T : T
>predicate : (x: {}) => x is T
>x : {}
>x : any
>T : T
>T : T
// 'res' should be of type 'number'.
const res = f((n): n is number => true);
>res : number
>f((n): n is number => true) : number
>f : <T>(predicate: (x: {}) => x is T) => T
>(n): n is number => true : (n: {}) => n is number
>n : {}
>n : any
>true : true
@@ -0,0 +1,10 @@
//// [typeInferenceTypePredicate2.ts]
[true, true, false, null]
.filter((thing): thing is boolean => thing !== null)
.map(thing => thing.toString());
//// [typeInferenceTypePredicate2.js]
[true, true, false, null]
.filter(function (thing) { return thing !== null; })
.map(function (thing) { return thing.toString(); });
@@ -0,0 +1,18 @@
=== tests/cases/compiler/typeInferenceTypePredicate2.ts ===
[true, true, false, null]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) .map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>[true, true, false, null] .filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
.filter((thing): thing is boolean => thing !== null)
>filter : Symbol(Array.filter, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 1, 13))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 1, 13))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 1, 13))
.map(thing => thing.toString());
>map : Symbol(Array.map, Decl(lib.d.ts, --, --))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 2, 9))
>thing.toString : Symbol(Object.toString, Decl(lib.d.ts, --, --))
>thing : Symbol(thing, Decl(typeInferenceTypePredicate2.ts, 2, 9))
>toString : Symbol(Object.toString, Decl(lib.d.ts, --, --))
@@ -0,0 +1,30 @@
=== tests/cases/compiler/typeInferenceTypePredicate2.ts ===
[true, true, false, null]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) .map(thing => thing.toString()) : string[]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) .map : <U>(callbackfn: (value: boolean, index: number, array: boolean[]) => U, thisArg?: any) => U[]
>[true, true, false, null] .filter((thing): thing is boolean => thing !== null) : boolean[]
>[true, true, false, null] .filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => any, thisArg?: any): boolean[]; }
>[true, true, false, null] : boolean[]
>true : true
>true : true
>false : false
>null : null
.filter((thing): thing is boolean => thing !== null)
>filter : { <S extends boolean>(callbackfn: (value: boolean, index: number, array: boolean[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: boolean, index: number, array: boolean[]) => any, thisArg?: any): boolean[]; }
>(thing): thing is boolean => thing !== null : (thing: boolean) => thing is boolean
>thing : boolean
>thing : any
>thing !== null : boolean
>thing : boolean
>null : null
.map(thing => thing.toString());
>map : <U>(callbackfn: (value: boolean, index: number, array: boolean[]) => U, thisArg?: any) => U[]
>thing => thing.toString() : (thing: boolean) => string
>thing : boolean
>thing.toString() : string
>thing.toString : () => string
>thing : boolean
>toString : () => string
@@ -0,0 +1,23 @@
//// [typePredicatesInUnion.ts]
interface A {
pred(x: {}): x is boolean;
}
interface B {
pred(x: {}): x is string;
}
type Or = A | B;
function f(o: Or, x: {}) {
if (o.pred(x)) {
x;
}
}
//// [typePredicatesInUnion.js]
function f(o, x) {
if (o.pred(x)) {
x;
}
}
@@ -0,0 +1,40 @@
=== tests/cases/compiler/typePredicatesInUnion.ts ===
interface A {
>A : Symbol(A, Decl(typePredicatesInUnion.ts, 0, 0))
pred(x: {}): x is boolean;
>pred : Symbol(A.pred, Decl(typePredicatesInUnion.ts, 0, 13))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 1, 9))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 1, 9))
}
interface B {
>B : Symbol(B, Decl(typePredicatesInUnion.ts, 2, 1))
pred(x: {}): x is string;
>pred : Symbol(B.pred, Decl(typePredicatesInUnion.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 4, 9))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 4, 9))
}
type Or = A | B;
>Or : Symbol(Or, Decl(typePredicatesInUnion.ts, 5, 1))
>A : Symbol(A, Decl(typePredicatesInUnion.ts, 0, 0))
>B : Symbol(B, Decl(typePredicatesInUnion.ts, 2, 1))
function f(o: Or, x: {}) {
>f : Symbol(f, Decl(typePredicatesInUnion.ts, 7, 16))
>o : Symbol(o, Decl(typePredicatesInUnion.ts, 9, 11))
>Or : Symbol(Or, Decl(typePredicatesInUnion.ts, 5, 1))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 9, 17))
if (o.pred(x)) {
>o.pred : Symbol(pred, Decl(typePredicatesInUnion.ts, 0, 13), Decl(typePredicatesInUnion.ts, 3, 13))
>o : Symbol(o, Decl(typePredicatesInUnion.ts, 9, 11))
>pred : Symbol(pred, Decl(typePredicatesInUnion.ts, 0, 13), Decl(typePredicatesInUnion.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 9, 17))
x;
>x : Symbol(x, Decl(typePredicatesInUnion.ts, 9, 17))
}
}
@@ -0,0 +1,41 @@
=== tests/cases/compiler/typePredicatesInUnion.ts ===
interface A {
>A : A
pred(x: {}): x is boolean;
>pred : (x: {}) => x is boolean
>x : {}
>x : any
}
interface B {
>B : B
pred(x: {}): x is string;
>pred : (x: {}) => x is string
>x : {}
>x : any
}
type Or = A | B;
>Or : Or
>A : A
>B : B
function f(o: Or, x: {}) {
>f : (o: Or, x: {}) => void
>o : Or
>Or : Or
>x : {}
if (o.pred(x)) {
>o.pred(x) : boolean
>o.pred : ((x: {}) => x is boolean) | ((x: {}) => x is string)
>o : Or
>pred : ((x: {}) => x is boolean) | ((x: {}) => x is string)
>x : {}
x;
>x : string | boolean
}
}
@@ -0,0 +1,11 @@
//// [typePredicatesInUnion2.ts]
declare function isString(x: any): x is string;
declare function isNumber(x: any): x is number;
declare function f(p: typeof isString | typeof isNumber): void;
f(isString);
f(isNumber);
//// [typePredicatesInUnion2.js]
f(isString);
f(isNumber);
@@ -0,0 +1,25 @@
=== tests/cases/compiler/typePredicatesInUnion2.ts ===
declare function isString(x: any): x is string;
>isString : Symbol(isString, Decl(typePredicatesInUnion2.ts, 0, 0))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 0, 26))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 0, 26))
declare function isNumber(x: any): x is number;
>isNumber : Symbol(isNumber, Decl(typePredicatesInUnion2.ts, 0, 47))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 1, 26))
>x : Symbol(x, Decl(typePredicatesInUnion2.ts, 1, 26))
declare function f(p: typeof isString | typeof isNumber): void;
>f : Symbol(f, Decl(typePredicatesInUnion2.ts, 1, 47))
>p : Symbol(p, Decl(typePredicatesInUnion2.ts, 2, 19))
>isString : Symbol(isString, Decl(typePredicatesInUnion2.ts, 0, 0))
>isNumber : Symbol(isNumber, Decl(typePredicatesInUnion2.ts, 0, 47))
f(isString);
>f : Symbol(f, Decl(typePredicatesInUnion2.ts, 1, 47))
>isString : Symbol(isString, Decl(typePredicatesInUnion2.ts, 0, 0))
f(isNumber);
>f : Symbol(f, Decl(typePredicatesInUnion2.ts, 1, 47))
>isNumber : Symbol(isNumber, Decl(typePredicatesInUnion2.ts, 0, 47))
@@ -0,0 +1,27 @@
=== tests/cases/compiler/typePredicatesInUnion2.ts ===
declare function isString(x: any): x is string;
>isString : (x: any) => x is string
>x : any
>x : any
declare function isNumber(x: any): x is number;
>isNumber : (x: any) => x is number
>x : any
>x : any
declare function f(p: typeof isString | typeof isNumber): void;
>f : (p: ((x: any) => x is string) | ((x: any) => x is number)) => void
>p : ((x: any) => x is string) | ((x: any) => x is number)
>isString : (x: any) => x is string
>isNumber : (x: any) => x is number
f(isString);
>f(isString) : void
>f : (p: ((x: any) => x is string) | ((x: any) => x is number)) => void
>isString : (x: any) => x is string
f(isNumber);
>f(isNumber) : void
>f : (p: ((x: any) => x is string) | ((x: any) => x is number)) => void
>isNumber : (x: any) => x is number
@@ -0,0 +1,25 @@
//// [typePredicatesInUnion_noMatch.ts]
interface A {
pred(x: {}, y: {}): x is boolean;
}
interface B {
pred(x: {}, y: {}): y is string;
}
type Or = A | B;
function f(o: Or, x: {}, y: {}) {
if (o.pred(x, y)) {
x;
y;
}
}
//// [typePredicatesInUnion_noMatch.js]
function f(o, x, y) {
if (o.pred(x, y)) {
x;
y;
}
}
@@ -0,0 +1,47 @@
=== tests/cases/compiler/typePredicatesInUnion_noMatch.ts ===
interface A {
>A : Symbol(A, Decl(typePredicatesInUnion_noMatch.ts, 0, 0))
pred(x: {}, y: {}): x is boolean;
>pred : Symbol(A.pred, Decl(typePredicatesInUnion_noMatch.ts, 0, 13))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 1, 9))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 1, 15))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 1, 9))
}
interface B {
>B : Symbol(B, Decl(typePredicatesInUnion_noMatch.ts, 2, 1))
pred(x: {}, y: {}): y is string;
>pred : Symbol(B.pred, Decl(typePredicatesInUnion_noMatch.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 4, 9))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 4, 15))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 4, 15))
}
type Or = A | B;
>Or : Symbol(Or, Decl(typePredicatesInUnion_noMatch.ts, 5, 1))
>A : Symbol(A, Decl(typePredicatesInUnion_noMatch.ts, 0, 0))
>B : Symbol(B, Decl(typePredicatesInUnion_noMatch.ts, 2, 1))
function f(o: Or, x: {}, y: {}) {
>f : Symbol(f, Decl(typePredicatesInUnion_noMatch.ts, 7, 16))
>o : Symbol(o, Decl(typePredicatesInUnion_noMatch.ts, 9, 11))
>Or : Symbol(Or, Decl(typePredicatesInUnion_noMatch.ts, 5, 1))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 9, 17))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 9, 24))
if (o.pred(x, y)) {
>o.pred : Symbol(pred, Decl(typePredicatesInUnion_noMatch.ts, 0, 13), Decl(typePredicatesInUnion_noMatch.ts, 3, 13))
>o : Symbol(o, Decl(typePredicatesInUnion_noMatch.ts, 9, 11))
>pred : Symbol(pred, Decl(typePredicatesInUnion_noMatch.ts, 0, 13), Decl(typePredicatesInUnion_noMatch.ts, 3, 13))
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 9, 17))
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 9, 24))
x;
>x : Symbol(x, Decl(typePredicatesInUnion_noMatch.ts, 9, 17))
y;
>y : Symbol(y, Decl(typePredicatesInUnion_noMatch.ts, 9, 24))
}
}
@@ -0,0 +1,48 @@
=== tests/cases/compiler/typePredicatesInUnion_noMatch.ts ===
interface A {
>A : A
pred(x: {}, y: {}): x is boolean;
>pred : (x: {}, y: {}) => x is boolean
>x : {}
>y : {}
>x : any
}
interface B {
>B : B
pred(x: {}, y: {}): y is string;
>pred : (x: {}, y: {}) => y is string
>x : {}
>y : {}
>y : any
}
type Or = A | B;
>Or : Or
>A : A
>B : B
function f(o: Or, x: {}, y: {}) {
>f : (o: Or, x: {}, y: {}) => void
>o : Or
>Or : Or
>x : {}
>y : {}
if (o.pred(x, y)) {
>o.pred(x, y) : boolean
>o.pred : ((x: {}, y: {}) => x is boolean) | ((x: {}, y: {}) => y is string)
>o : Or
>pred : ((x: {}, y: {}) => x is boolean) | ((x: {}, y: {}) => y is string)
>x : {}
>y : {}
x;
>x : {}
y;
>y : {}
}
}
@@ -0,0 +1,3 @@
declare function f<T>(predicate: (x: {}) => x is T): T;
// 'res' should be of type 'number'.
const res = f((n): n is number => true);
@@ -0,0 +1,3 @@
[true, true, false, null]
.filter((thing): thing is boolean => thing !== null)
.map(thing => thing.toString());
@@ -0,0 +1,14 @@
interface A {
pred(x: {}): x is boolean;
}
interface B {
pred(x: {}): x is string;
}
type Or = A | B;
function f(o: Or, x: {}) {
if (o.pred(x)) {
x;
}
}
@@ -0,0 +1,5 @@
declare function isString(x: any): x is string;
declare function isNumber(x: any): x is number;
declare function f(p: typeof isString | typeof isNumber): void;
f(isString);
f(isNumber);
@@ -0,0 +1,15 @@
interface A {
pred(x: {}, y: {}): x is boolean;
}
interface B {
pred(x: {}, y: {}): y is string;
}
type Or = A | B;
function f(o: Or, x: {}, y: {}) {
if (o.pred(x, y)) {
x;
y;
}
}
@@ -296,6 +296,9 @@ define(function () {
isArray = ('isArray' in Array) ?
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
isArray = 'isArray' in Array
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
: Array.isArray;
function equalIC(a, b) {
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
@@ -966,7 +969,7 @@ define(function () {
// should not be replaced by a completely new object - just overwrite existing methods
MobileDetect._impl = impl;
MobileDetect.version = '1.3.3 2016-07-31';
return MobileDetect;