Merge pull request #3262 from tinganho/customTypeGuard2
Custom type guard function
This commit is contained in:
commit
6e69a9e380
27 changed files with 2842 additions and 41 deletions
0
bin/tsc
Normal file → Executable file
0
bin/tsc
Normal file → Executable file
|
@ -97,8 +97,8 @@ module ts {
|
||||||
let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||||
let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
|
||||||
|
|
||||||
let anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false);
|
let anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false);
|
||||||
let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false);
|
let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false);
|
||||||
|
|
||||||
let globals: SymbolTable = {};
|
let globals: SymbolTable = {};
|
||||||
|
|
||||||
|
@ -1352,7 +1352,15 @@ module ts {
|
||||||
function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string {
|
function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string {
|
||||||
let writer = getSingleLineStringWriter();
|
let writer = getSingleLineStringWriter();
|
||||||
getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
|
getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning);
|
||||||
|
let result = writer.string();
|
||||||
|
releaseStringWriter(writer);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string {
|
||||||
|
let writer = getSingleLineStringWriter();
|
||||||
|
getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags);
|
||||||
let result = writer.string();
|
let result = writer.string();
|
||||||
releaseStringWriter(writer);
|
releaseStringWriter(writer);
|
||||||
|
|
||||||
|
@ -1362,7 +1370,6 @@ module ts {
|
||||||
function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string {
|
function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string {
|
||||||
let writer = getSingleLineStringWriter();
|
let writer = getSingleLineStringWriter();
|
||||||
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
|
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
|
||||||
|
|
||||||
let result = writer.string();
|
let result = writer.string();
|
||||||
releaseStringWriter(writer);
|
releaseStringWriter(writer);
|
||||||
|
|
||||||
|
@ -1370,7 +1377,6 @@ module ts {
|
||||||
if (maxLength && result.length >= maxLength) {
|
if (maxLength && result.length >= maxLength) {
|
||||||
result = result.substr(0, maxLength - "...".length) + "...";
|
result = result.substr(0, maxLength - "...".length) + "...";
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2782,7 +2788,7 @@ module ts {
|
||||||
|
|
||||||
function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers {
|
function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers {
|
||||||
if (!(<InterfaceTypeWithDeclaredMembers>type).declaredProperties) {
|
if (!(<InterfaceTypeWithDeclaredMembers>type).declaredProperties) {
|
||||||
var symbol = type.symbol;
|
let symbol = type.symbol;
|
||||||
(<InterfaceTypeWithDeclaredMembers>type).declaredProperties = getNamedMembers(symbol.members);
|
(<InterfaceTypeWithDeclaredMembers>type).declaredProperties = getNamedMembers(symbol.members);
|
||||||
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]);
|
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]);
|
||||||
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]);
|
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]);
|
||||||
|
@ -2833,12 +2839,13 @@ module ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[],
|
function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], parameters: Symbol[],
|
||||||
resolvedReturnType: Type, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature {
|
resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasStringLiterals: boolean): Signature {
|
||||||
let sig = new Signature(checker);
|
let sig = new Signature(checker);
|
||||||
sig.declaration = declaration;
|
sig.declaration = declaration;
|
||||||
sig.typeParameters = typeParameters;
|
sig.typeParameters = typeParameters;
|
||||||
sig.parameters = parameters;
|
sig.parameters = parameters;
|
||||||
sig.resolvedReturnType = resolvedReturnType;
|
sig.resolvedReturnType = resolvedReturnType;
|
||||||
|
sig.typePredicate = typePredicate;
|
||||||
sig.minArgumentCount = minArgumentCount;
|
sig.minArgumentCount = minArgumentCount;
|
||||||
sig.hasRestParameter = hasRestParameter;
|
sig.hasRestParameter = hasRestParameter;
|
||||||
sig.hasStringLiterals = hasStringLiterals;
|
sig.hasStringLiterals = hasStringLiterals;
|
||||||
|
@ -2846,7 +2853,7 @@ module ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneSignature(sig: Signature): Signature {
|
function cloneSignature(sig: Signature): Signature {
|
||||||
return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType,
|
return createSignature(sig.declaration, sig.typeParameters, sig.parameters, sig.resolvedReturnType, sig.typePredicate,
|
||||||
sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals);
|
sig.minArgumentCount, sig.hasRestParameter, sig.hasStringLiterals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2863,7 +2870,7 @@ module ts {
|
||||||
return signature;
|
return signature;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, 0, false, false)];
|
return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTupleTypeMemberSymbols(memberTypes: Type[]): SymbolTable {
|
function createTupleTypeMemberSymbols(memberTypes: Type[]): SymbolTable {
|
||||||
|
@ -3239,11 +3246,20 @@ module ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
let returnType: Type;
|
let returnType: Type;
|
||||||
|
let typePredicate: TypePredicate;
|
||||||
if (classType) {
|
if (classType) {
|
||||||
returnType = classType;
|
returnType = classType;
|
||||||
}
|
}
|
||||||
else if (declaration.type) {
|
else if (declaration.type) {
|
||||||
returnType = getTypeFromTypeNode(declaration.type);
|
returnType = getTypeFromTypeNode(declaration.type);
|
||||||
|
if (declaration.type.kind === SyntaxKind.TypePredicate) {
|
||||||
|
let typePredicateNode = <TypePredicateNode>declaration.type;
|
||||||
|
typePredicate = {
|
||||||
|
parameterName: typePredicateNode.parameterName ? typePredicateNode.parameterName.text : undefined,
|
||||||
|
parameterIndex: typePredicateNode.parameterName ? getTypePredicateParameterIndex(declaration.parameters, typePredicateNode.parameterName) : undefined,
|
||||||
|
type: getTypeFromTypeNode(typePredicateNode.type)
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TypeScript 1.0 spec (April 2014):
|
// TypeScript 1.0 spec (April 2014):
|
||||||
|
@ -3258,7 +3274,7 @@ module ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType,
|
links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, typePredicate,
|
||||||
minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
|
minArgumentCount, hasRestParameter(declaration), hasStringLiterals);
|
||||||
}
|
}
|
||||||
return links.resolvedSignature;
|
return links.resolvedSignature;
|
||||||
|
@ -3849,6 +3865,8 @@ module ts {
|
||||||
return getTypeFromStringLiteral(<StringLiteral>node);
|
return getTypeFromStringLiteral(<StringLiteral>node);
|
||||||
case SyntaxKind.TypeReference:
|
case SyntaxKind.TypeReference:
|
||||||
return getTypeFromTypeReferenceOrExpressionWithTypeArguments(<TypeReferenceNode>node);
|
return getTypeFromTypeReferenceOrExpressionWithTypeArguments(<TypeReferenceNode>node);
|
||||||
|
case SyntaxKind.TypePredicate:
|
||||||
|
return booleanType;
|
||||||
case SyntaxKind.ExpressionWithTypeArguments:
|
case SyntaxKind.ExpressionWithTypeArguments:
|
||||||
return getTypeFromTypeReferenceOrExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
|
return getTypeFromTypeReferenceOrExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
|
||||||
case SyntaxKind.TypeQuery:
|
case SyntaxKind.TypeQuery:
|
||||||
|
@ -3968,13 +3986,22 @@ module ts {
|
||||||
|
|
||||||
function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature {
|
function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature {
|
||||||
let freshTypeParameters: TypeParameter[];
|
let freshTypeParameters: TypeParameter[];
|
||||||
|
let freshTypePredicate: TypePredicate;
|
||||||
if (signature.typeParameters && !eraseTypeParameters) {
|
if (signature.typeParameters && !eraseTypeParameters) {
|
||||||
freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter);
|
freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter);
|
||||||
mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
|
mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
|
||||||
}
|
}
|
||||||
|
if (signature.typePredicate) {
|
||||||
|
freshTypePredicate = {
|
||||||
|
parameterName: signature.typePredicate.parameterName,
|
||||||
|
parameterIndex: signature.typePredicate.parameterIndex,
|
||||||
|
type: instantiateType(signature.typePredicate.type, mapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
let result = createSignature(signature.declaration, freshTypeParameters,
|
let result = createSignature(signature.declaration, freshTypeParameters,
|
||||||
instantiateList(signature.parameters, mapper, instantiateSymbol),
|
instantiateList(signature.parameters, mapper, instantiateSymbol),
|
||||||
signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined,
|
signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined,
|
||||||
|
freshTypePredicate,
|
||||||
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
|
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
|
||||||
result.target = signature;
|
result.target = signature;
|
||||||
result.mapper = mapper;
|
result.mapper = mapper;
|
||||||
|
@ -4631,6 +4658,44 @@ module ts {
|
||||||
}
|
}
|
||||||
result &= related;
|
result &= related;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (source.typePredicate && target.typePredicate) {
|
||||||
|
let hasDifferentParameterIndex = source.typePredicate.parameterIndex !== target.typePredicate.parameterIndex;
|
||||||
|
let hasDifferentTypes: boolean;
|
||||||
|
if (hasDifferentParameterIndex ||
|
||||||
|
(hasDifferentTypes = !isTypeIdenticalTo(source.typePredicate.type, target.typePredicate.type))) {
|
||||||
|
|
||||||
|
if (reportErrors) {
|
||||||
|
let sourceParamText = source.typePredicate.parameterName;
|
||||||
|
let targetParamText = target.typePredicate.parameterName;
|
||||||
|
let sourceTypeText = typeToString(source.typePredicate.type);
|
||||||
|
let targetTypeText = typeToString(target.typePredicate.type);
|
||||||
|
|
||||||
|
if (hasDifferentParameterIndex) {
|
||||||
|
reportError(Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1,
|
||||||
|
sourceParamText,
|
||||||
|
targetParamText);
|
||||||
|
}
|
||||||
|
else if (hasDifferentTypes) {
|
||||||
|
reportError(Diagnostics.Type_0_is_not_assignable_to_type_1,
|
||||||
|
sourceTypeText,
|
||||||
|
targetTypeText);
|
||||||
|
}
|
||||||
|
|
||||||
|
reportError(Diagnostics.Type_predicate_0_is_not_assignable_to_1,
|
||||||
|
`${sourceParamText} is ${sourceTypeText}`,
|
||||||
|
`${targetParamText} is ${targetTypeText}`);
|
||||||
|
}
|
||||||
|
return Ternary.False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!source.typePredicate && target.typePredicate) {
|
||||||
|
if (reportErrors) {
|
||||||
|
reportError(Diagnostics.Signature_0_must_have_a_type_predicate, signatureToString(source));
|
||||||
|
}
|
||||||
|
return Ternary.False;
|
||||||
|
}
|
||||||
|
|
||||||
let t = getReturnTypeOfSignature(target);
|
let t = getReturnTypeOfSignature(target);
|
||||||
if (t === voidType) return result;
|
if (t === voidType) return result;
|
||||||
let s = getReturnTypeOfSignature(source);
|
let s = getReturnTypeOfSignature(source);
|
||||||
|
@ -5163,6 +5228,16 @@ module ts {
|
||||||
|
|
||||||
function inferFromSignature(source: Signature, target: Signature) {
|
function inferFromSignature(source: Signature, target: Signature) {
|
||||||
forEachMatchingParameterType(source, target, inferFromTypes);
|
forEachMatchingParameterType(source, target, inferFromTypes);
|
||||||
|
if (source.typePredicate && target.typePredicate) {
|
||||||
|
if (target.typePredicate.parameterIndex === source.typePredicate.parameterIndex) {
|
||||||
|
// Return types from type predicates are treated as booleans. In order to infer types
|
||||||
|
// from type predicates we would need to infer from the type of type predicates. Since
|
||||||
|
// we can't infer any type information from the return types — we can just add a return
|
||||||
|
// statement after the below infer type statement.
|
||||||
|
inferFromTypes(source.typePredicate.type, target.typePredicate.type);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
|
inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5547,7 +5622,7 @@ module ts {
|
||||||
let targetType: Type;
|
let targetType: Type;
|
||||||
let prototypeProperty = getPropertyOfType(rightType, "prototype");
|
let prototypeProperty = getPropertyOfType(rightType, "prototype");
|
||||||
if (prototypeProperty) {
|
if (prototypeProperty) {
|
||||||
// Target type is type of the protoype property
|
// Target type is type of the prototype property
|
||||||
let prototypePropertyType = getTypeOfSymbol(prototypeProperty);
|
let prototypePropertyType = getTypeOfSymbol(prototypeProperty);
|
||||||
if (!isTypeAny(prototypePropertyType)) {
|
if (!isTypeAny(prototypePropertyType)) {
|
||||||
targetType = prototypePropertyType;
|
targetType = prototypePropertyType;
|
||||||
|
@ -5563,30 +5638,56 @@ module ts {
|
||||||
else if (rightType.flags & TypeFlags.Anonymous) {
|
else if (rightType.flags & TypeFlags.Anonymous) {
|
||||||
constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
|
constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constructSignatures && constructSignatures.length) {
|
if (constructSignatures && constructSignatures.length) {
|
||||||
targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature))));
|
targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targetType) {
|
if (targetType) {
|
||||||
// Narrow to the target type if it's a subtype of the current type
|
return getNarrowedType(type, targetType);
|
||||||
if (isTypeSubtypeOf(targetType, type)) {
|
|
||||||
return targetType;
|
|
||||||
}
|
|
||||||
// If the current type is a union type, remove all constituents that aren't subtypes of the target.
|
|
||||||
if (type.flags & TypeFlags.Union) {
|
|
||||||
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, targetType)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNarrowedType(originalType: Type, narrowedTypeCandidate: Type) {
|
||||||
|
// Narrow to the target type if it's a subtype of the current type
|
||||||
|
if (isTypeSubtypeOf(narrowedTypeCandidate, originalType)) {
|
||||||
|
return narrowedTypeCandidate;
|
||||||
|
}
|
||||||
|
// If the current type is a union type, remove all constituents that aren't subtypes of the target.
|
||||||
|
if (originalType.flags & TypeFlags.Union) {
|
||||||
|
return getUnionType(filter((<UnionType>originalType).types, t => isTypeSubtypeOf(t, narrowedTypeCandidate)));
|
||||||
|
}
|
||||||
|
return originalType;
|
||||||
|
}
|
||||||
|
|
||||||
|
function narrowTypeByTypePredicate(type: Type, expr: CallExpression, assumeTrue: boolean): Type {
|
||||||
|
if (type.flags & TypeFlags.Any) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
let signature = getResolvedSignature(expr);
|
||||||
|
|
||||||
|
if (signature.typePredicate &&
|
||||||
|
getSymbolAtLocation(expr.arguments[signature.typePredicate.parameterIndex]) === symbol) {
|
||||||
|
|
||||||
|
if (!assumeTrue) {
|
||||||
|
if (type.flags & TypeFlags.Union) {
|
||||||
|
return getUnionType(filter((<UnionType>type).types, t => !isTypeSubtypeOf(t, signature.typePredicate.type)));
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
return getNarrowedType(type, signature.typePredicate.type);
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
// Narrow the given type based on the given expression having the assumed boolean value. The returned type
|
// Narrow the given type based on the given expression having the assumed boolean value. The returned type
|
||||||
// will be a subtype or the same type as the argument.
|
// will be a subtype or the same type as the argument.
|
||||||
function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type {
|
function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type {
|
||||||
switch (expr.kind) {
|
switch (expr.kind) {
|
||||||
|
case SyntaxKind.CallExpression:
|
||||||
|
return narrowTypeByTypePredicate(type, <CallExpression>expr, assumeTrue);
|
||||||
case SyntaxKind.ParenthesizedExpression:
|
case SyntaxKind.ParenthesizedExpression:
|
||||||
return narrowType(type, (<ParenthesizedExpression>expr).expression, assumeTrue);
|
return narrowType(type, (<ParenthesizedExpression>expr).expression, assumeTrue);
|
||||||
case SyntaxKind.BinaryExpression:
|
case SyntaxKind.BinaryExpression:
|
||||||
|
@ -8506,6 +8607,34 @@ module ts {
|
||||||
node.kind === SyntaxKind.FunctionExpression;
|
node.kind === SyntaxKind.FunctionExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTypePredicateParameterIndex(parameterList: NodeArray<ParameterDeclaration>, parameter: Identifier): number {
|
||||||
|
if (parameterList) {
|
||||||
|
for (let i = 0; i < parameterList.length; i++) {
|
||||||
|
let param = parameterList[i];
|
||||||
|
if (param.name.kind === SyntaxKind.Identifier &&
|
||||||
|
(<Identifier>param.name).text === parameter.text) {
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isInLegalTypePredicatePosition(node: Node): boolean {
|
||||||
|
switch (node.parent.kind) {
|
||||||
|
case SyntaxKind.ArrowFunction:
|
||||||
|
case SyntaxKind.CallSignature:
|
||||||
|
case SyntaxKind.FunctionDeclaration:
|
||||||
|
case SyntaxKind.FunctionExpression:
|
||||||
|
case SyntaxKind.FunctionType:
|
||||||
|
case SyntaxKind.MethodDeclaration:
|
||||||
|
case SyntaxKind.MethodSignature:
|
||||||
|
return node === (<SignatureDeclaration>node.parent).type;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function checkSignatureDeclaration(node: SignatureDeclaration) {
|
function checkSignatureDeclaration(node: SignatureDeclaration) {
|
||||||
// Grammar checking
|
// Grammar checking
|
||||||
if (node.kind === SyntaxKind.IndexSignature) {
|
if (node.kind === SyntaxKind.IndexSignature) {
|
||||||
|
@ -8523,7 +8652,65 @@ module ts {
|
||||||
forEach(node.parameters, checkParameter);
|
forEach(node.parameters, checkParameter);
|
||||||
|
|
||||||
if (node.type) {
|
if (node.type) {
|
||||||
checkSourceElement(node.type);
|
if (node.type.kind === SyntaxKind.TypePredicate) {
|
||||||
|
let typePredicate = getSignatureFromDeclaration(node).typePredicate;
|
||||||
|
let typePredicateNode = <TypePredicateNode>node.type;
|
||||||
|
if (isInLegalTypePredicatePosition(typePredicateNode)) {
|
||||||
|
if (typePredicate.parameterIndex >= 0) {
|
||||||
|
if (node.parameters[typePredicate.parameterIndex].dotDotDotToken) {
|
||||||
|
error(typePredicateNode.parameterName,
|
||||||
|
Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checkTypeAssignableTo(typePredicate.type,
|
||||||
|
getTypeAtLocation(node.parameters[typePredicate.parameterIndex]),
|
||||||
|
typePredicateNode.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typePredicateNode.parameterName) {
|
||||||
|
let hasReportedError = false;
|
||||||
|
for (var param of node.parameters) {
|
||||||
|
if (hasReportedError) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (param.name.kind === SyntaxKind.ObjectBindingPattern ||
|
||||||
|
param.name.kind === SyntaxKind.ArrayBindingPattern) {
|
||||||
|
|
||||||
|
(function checkBindingPattern(pattern: BindingPattern) {
|
||||||
|
for (let element of pattern.elements) {
|
||||||
|
if (element.name.kind === SyntaxKind.Identifier &&
|
||||||
|
(<Identifier>element.name).text === typePredicate.parameterName) {
|
||||||
|
|
||||||
|
error(typePredicateNode.parameterName,
|
||||||
|
Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern,
|
||||||
|
typePredicate.parameterName);
|
||||||
|
hasReportedError = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (element.name.kind === SyntaxKind.ArrayBindingPattern ||
|
||||||
|
element.name.kind === SyntaxKind.ObjectBindingPattern) {
|
||||||
|
|
||||||
|
checkBindingPattern(<BindingPattern>element.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(<BindingPattern>param.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasReportedError) {
|
||||||
|
error(typePredicateNode.parameterName,
|
||||||
|
Diagnostics.Cannot_find_parameter_0,
|
||||||
|
typePredicate.parameterName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
error(typePredicateNode,
|
||||||
|
Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checkSourceElement(node.type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (produceDiagnostics) {
|
if (produceDiagnostics) {
|
||||||
|
@ -10085,9 +10272,10 @@ module ts {
|
||||||
if (node.expression) {
|
if (node.expression) {
|
||||||
let func = getContainingFunction(node);
|
let func = getContainingFunction(node);
|
||||||
if (func) {
|
if (func) {
|
||||||
let returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
|
let signature = getSignatureFromDeclaration(func);
|
||||||
|
let returnType = getReturnTypeOfSignature(signature);
|
||||||
let exprType = checkExpressionCached(node.expression);
|
let exprType = checkExpressionCached(node.expression);
|
||||||
|
|
||||||
if (func.asteriskToken) {
|
if (func.asteriskToken) {
|
||||||
// A generator does not need its return expressions checked against its return type.
|
// A generator does not need its return expressions checked against its return type.
|
||||||
// Instead, the yield expressions are checked against the element type.
|
// Instead, the yield expressions are checked against the element type.
|
||||||
|
@ -10104,7 +10292,7 @@ module ts {
|
||||||
error(node.expression, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
|
error(node.expression, Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) {
|
else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func) || signature.typePredicate) {
|
||||||
checkTypeAssignableTo(exprType, returnType, node.expression, /*headMessage*/ undefined);
|
checkTypeAssignableTo(exprType, returnType, node.expression, /*headMessage*/ undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11157,6 +11345,12 @@ module ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkTypePredicate(node: TypePredicateNode) {
|
||||||
|
if(!isInLegalTypePredicatePosition(node)) {
|
||||||
|
error(node, Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkSourceElement(node: Node): void {
|
function checkSourceElement(node: Node): void {
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
|
@ -11184,6 +11378,8 @@ module ts {
|
||||||
return checkAccessorDeclaration(<AccessorDeclaration>node);
|
return checkAccessorDeclaration(<AccessorDeclaration>node);
|
||||||
case SyntaxKind.TypeReference:
|
case SyntaxKind.TypeReference:
|
||||||
return checkTypeReferenceNode(<TypeReferenceNode>node);
|
return checkTypeReferenceNode(<TypeReferenceNode>node);
|
||||||
|
case SyntaxKind.TypePredicate:
|
||||||
|
return checkTypePredicate(<TypePredicateNode>node);
|
||||||
case SyntaxKind.TypeQuery:
|
case SyntaxKind.TypeQuery:
|
||||||
return checkTypeQuery(<TypeQueryNode>node);
|
return checkTypeQuery(<TypeQueryNode>node);
|
||||||
case SyntaxKind.TypeLiteral:
|
case SyntaxKind.TypeLiteral:
|
||||||
|
|
|
@ -179,6 +179,13 @@ module ts {
|
||||||
Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." },
|
Generators_are_not_allowed_in_an_ambient_context: { code: 1221, category: DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." },
|
||||||
An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." },
|
An_overload_signature_cannot_be_declared_as_a_generator: { code: 1222, category: DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." },
|
||||||
_0_tag_already_specified: { code: 1223, category: DiagnosticCategory.Error, key: "'{0}' tag already specified." },
|
_0_tag_already_specified: { code: 1223, category: DiagnosticCategory.Error, key: "'{0}' tag already specified." },
|
||||||
|
Signature_0_must_have_a_type_predicate: { code: 1224, category: DiagnosticCategory.Error, key: "Signature '{0}' must have a type predicate." },
|
||||||
|
Cannot_find_parameter_0: { code: 1225, category: DiagnosticCategory.Error, key: "Cannot find parameter '{0}'." },
|
||||||
|
Type_predicate_0_is_not_assignable_to_1: { code: 1226, category: DiagnosticCategory.Error, key: "Type predicate '{0}' is not assignable to '{1}'." },
|
||||||
|
Parameter_0_is_not_in_the_same_position_as_parameter_1: { code: 1227, category: DiagnosticCategory.Error, key: "Parameter '{0}' is not in the same position as parameter '{1}'." },
|
||||||
|
A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: { code: 1228, category: DiagnosticCategory.Error, key: "A type predicate is only allowed in return type position for functions and methods." },
|
||||||
|
A_type_predicate_cannot_reference_a_rest_parameter: { code: 1229, category: DiagnosticCategory.Error, key: "A type predicate cannot reference a rest parameter." },
|
||||||
|
A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: { code: 1230, category: DiagnosticCategory.Error, key: "A type predicate cannot reference element '{0}' in a binding pattern." },
|
||||||
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
|
||||||
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
|
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
|
||||||
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
|
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
|
||||||
|
|
|
@ -703,6 +703,35 @@
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
"code": 1223
|
"code": 1223
|
||||||
},
|
},
|
||||||
|
"Signature '{0}' must have a type predicate.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1224
|
||||||
|
},
|
||||||
|
"Cannot find parameter '{0}'.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1225
|
||||||
|
},
|
||||||
|
"Type predicate '{0}' is not assignable to '{1}'.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1226
|
||||||
|
},
|
||||||
|
"Parameter '{0}' is not in the same position as parameter '{1}'.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1227
|
||||||
|
},
|
||||||
|
"A type predicate is only allowed in return type position for functions and methods.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1228
|
||||||
|
},
|
||||||
|
"A type predicate cannot reference a rest parameter.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1229
|
||||||
|
},
|
||||||
|
"A type predicate cannot reference element '{0}' in a binding pattern.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 1230
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
"Duplicate identifier '{0}'.": {
|
"Duplicate identifier '{0}'.": {
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
|
|
|
@ -103,6 +103,9 @@ module ts {
|
||||||
case SyntaxKind.TypeReference:
|
case SyntaxKind.TypeReference:
|
||||||
return visitNode(cbNode, (<TypeReferenceNode>node).typeName) ||
|
return visitNode(cbNode, (<TypeReferenceNode>node).typeName) ||
|
||||||
visitNodes(cbNodes, (<TypeReferenceNode>node).typeArguments);
|
visitNodes(cbNodes, (<TypeReferenceNode>node).typeArguments);
|
||||||
|
case SyntaxKind.TypePredicate:
|
||||||
|
return visitNode(cbNode, (<TypePredicateNode>node).parameterName) ||
|
||||||
|
visitNode(cbNode, (<TypePredicateNode>node).type);
|
||||||
case SyntaxKind.TypeQuery:
|
case SyntaxKind.TypeQuery:
|
||||||
return visitNode(cbNode, (<TypeQueryNode>node).exprName);
|
return visitNode(cbNode, (<TypeQueryNode>node).exprName);
|
||||||
case SyntaxKind.TypeLiteral:
|
case SyntaxKind.TypeLiteral:
|
||||||
|
@ -1897,9 +1900,17 @@ module ts {
|
||||||
|
|
||||||
// TYPES
|
// TYPES
|
||||||
|
|
||||||
function parseTypeReference(): TypeReferenceNode {
|
function parseTypeReferenceOrTypePredicate(): TypeReferenceNode | TypePredicateNode {
|
||||||
let node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
|
let typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected);
|
||||||
node.typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected);
|
if (typeName.kind === SyntaxKind.Identifier && token === SyntaxKind.IsKeyword) {
|
||||||
|
nextToken();
|
||||||
|
let node = <TypePredicateNode>createNode(SyntaxKind.TypePredicate, typeName.pos);
|
||||||
|
node.parameterName = <Identifier>typeName;
|
||||||
|
node.type = parseType();
|
||||||
|
return finishNode(node);
|
||||||
|
}
|
||||||
|
let node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference, typeName.pos);
|
||||||
|
node.typeName = typeName;
|
||||||
if (!scanner.hasPrecedingLineBreak() && token === SyntaxKind.LessThanToken) {
|
if (!scanner.hasPrecedingLineBreak() && token === SyntaxKind.LessThanToken) {
|
||||||
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||||
}
|
}
|
||||||
|
@ -2336,7 +2347,7 @@ module ts {
|
||||||
case SyntaxKind.SymbolKeyword:
|
case SyntaxKind.SymbolKeyword:
|
||||||
// If these are followed by a dot, then parse these out as a dotted type reference instead.
|
// If these are followed by a dot, then parse these out as a dotted type reference instead.
|
||||||
let node = tryParse(parseKeywordAndNoDot);
|
let node = tryParse(parseKeywordAndNoDot);
|
||||||
return node || parseTypeReference();
|
return node || parseTypeReferenceOrTypePredicate();
|
||||||
case SyntaxKind.VoidKeyword:
|
case SyntaxKind.VoidKeyword:
|
||||||
return parseTokenNode<TypeNode>();
|
return parseTokenNode<TypeNode>();
|
||||||
case SyntaxKind.TypeOfKeyword:
|
case SyntaxKind.TypeOfKeyword:
|
||||||
|
@ -2348,7 +2359,7 @@ module ts {
|
||||||
case SyntaxKind.OpenParenToken:
|
case SyntaxKind.OpenParenToken:
|
||||||
return parseParenthesizedType();
|
return parseParenthesizedType();
|
||||||
default:
|
default:
|
||||||
return parseTypeReference();
|
return parseTypeReferenceOrTypePredicate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ module ts {
|
||||||
"in": SyntaxKind.InKeyword,
|
"in": SyntaxKind.InKeyword,
|
||||||
"instanceof": SyntaxKind.InstanceOfKeyword,
|
"instanceof": SyntaxKind.InstanceOfKeyword,
|
||||||
"interface": SyntaxKind.InterfaceKeyword,
|
"interface": SyntaxKind.InterfaceKeyword,
|
||||||
|
"is": SyntaxKind.IsKeyword,
|
||||||
"let": SyntaxKind.LetKeyword,
|
"let": SyntaxKind.LetKeyword,
|
||||||
"module": SyntaxKind.ModuleKeyword,
|
"module": SyntaxKind.ModuleKeyword,
|
||||||
"namespace": SyntaxKind.NamespaceKeyword,
|
"namespace": SyntaxKind.NamespaceKeyword,
|
||||||
|
|
|
@ -145,6 +145,7 @@ module ts {
|
||||||
ConstructorKeyword,
|
ConstructorKeyword,
|
||||||
DeclareKeyword,
|
DeclareKeyword,
|
||||||
GetKeyword,
|
GetKeyword,
|
||||||
|
IsKeyword,
|
||||||
ModuleKeyword,
|
ModuleKeyword,
|
||||||
NamespaceKeyword,
|
NamespaceKeyword,
|
||||||
RequireKeyword,
|
RequireKeyword,
|
||||||
|
@ -177,6 +178,7 @@ module ts {
|
||||||
ConstructSignature,
|
ConstructSignature,
|
||||||
IndexSignature,
|
IndexSignature,
|
||||||
// Type
|
// Type
|
||||||
|
TypePredicate,
|
||||||
TypeReference,
|
TypeReference,
|
||||||
FunctionType,
|
FunctionType,
|
||||||
ConstructorType,
|
ConstructorType,
|
||||||
|
@ -614,6 +616,11 @@ module ts {
|
||||||
typeArguments?: NodeArray<TypeNode>;
|
typeArguments?: NodeArray<TypeNode>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TypePredicateNode extends TypeNode {
|
||||||
|
parameterName: Identifier;
|
||||||
|
type: TypeNode;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TypeQueryNode extends TypeNode {
|
export interface TypeQueryNode extends TypeNode {
|
||||||
exprName: EntityName;
|
exprName: EntityName;
|
||||||
}
|
}
|
||||||
|
@ -1386,6 +1393,12 @@ module ts {
|
||||||
NotAccessible,
|
NotAccessible,
|
||||||
CannotBeNamed
|
CannotBeNamed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TypePredicate {
|
||||||
|
parameterName: string;
|
||||||
|
parameterIndex: number;
|
||||||
|
type: Type;
|
||||||
|
}
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration;
|
export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration;
|
||||||
|
@ -1593,12 +1606,12 @@ module ts {
|
||||||
Union = 0x00004000, // Union
|
Union = 0x00004000, // Union
|
||||||
Anonymous = 0x00008000, // Anonymous
|
Anonymous = 0x00008000, // Anonymous
|
||||||
Instantiated = 0x00010000, // Instantiated anonymous type
|
Instantiated = 0x00010000, // Instantiated anonymous type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
FromSignature = 0x00020000, // Created for signature assignment check
|
FromSignature = 0x00020000, // Created for signature assignment check
|
||||||
ObjectLiteral = 0x00040000, // Originates in an object literal
|
ObjectLiteral = 0x00040000, // Originates in an object literal
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsUndefinedOrNull = 0x00080000, // Type is or contains Undefined or Null type
|
ContainsUndefinedOrNull = 0x00080000, // Type is or contains Undefined or Null type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsObjectLiteral = 0x00100000, // Type is or contains object literal type
|
ContainsObjectLiteral = 0x00100000, // Type is or contains object literal type
|
||||||
ESSymbol = 0x00200000, // Type of symbol primitive introduced in ES6
|
ESSymbol = 0x00200000, // Type of symbol primitive introduced in ES6
|
||||||
|
|
||||||
|
@ -1714,6 +1727,7 @@ module ts {
|
||||||
declaration: SignatureDeclaration; // Originating declaration
|
declaration: SignatureDeclaration; // Originating declaration
|
||||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||||
parameters: Symbol[]; // Parameters
|
parameters: Symbol[]; // Parameters
|
||||||
|
typePredicate?: TypePredicate; // Type predicate
|
||||||
/* @internal */
|
/* @internal */
|
||||||
resolvedReturnType: Type; // Resolved return type
|
resolvedReturnType: Type; // Resolved return type
|
||||||
/* @internal */
|
/* @internal */
|
||||||
|
|
|
@ -75,26 +75,26 @@ function delint(sourceFile) {
|
||||||
delintNode(sourceFile);
|
delintNode(sourceFile);
|
||||||
function delintNode(node) {
|
function delintNode(node) {
|
||||||
switch (node.kind) {
|
switch (node.kind) {
|
||||||
case 187 /* ForStatement */:
|
case 189 /* ForStatement */:
|
||||||
case 188 /* ForInStatement */:
|
case 190 /* ForInStatement */:
|
||||||
case 186 /* WhileStatement */:
|
case 188 /* WhileStatement */:
|
||||||
case 185 /* DoStatement */:
|
case 187 /* DoStatement */:
|
||||||
if (node.statement.kind !== 180 /* Block */) {
|
if (node.statement.kind !== 182 /* Block */) {
|
||||||
report(node, "A looping statement's contents should be wrapped in a block body.");
|
report(node, "A looping statement's contents should be wrapped in a block body.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 184 /* IfStatement */:
|
case 186 /* IfStatement */:
|
||||||
var ifStatement = node;
|
var ifStatement = node;
|
||||||
if (ifStatement.thenStatement.kind !== 180 /* Block */) {
|
if (ifStatement.thenStatement.kind !== 182 /* Block */) {
|
||||||
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
|
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
|
||||||
}
|
}
|
||||||
if (ifStatement.elseStatement &&
|
if (ifStatement.elseStatement &&
|
||||||
ifStatement.elseStatement.kind !== 180 /* Block */ &&
|
ifStatement.elseStatement.kind !== 182 /* Block */ &&
|
||||||
ifStatement.elseStatement.kind !== 184 /* IfStatement */) {
|
ifStatement.elseStatement.kind !== 186 /* IfStatement */) {
|
||||||
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
|
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 170 /* BinaryExpression */:
|
case 172 /* BinaryExpression */:
|
||||||
var op = node.operatorToken.kind;
|
var op = node.operatorToken.kind;
|
||||||
if (op === 28 /* EqualsEqualsToken */ || op == 29 /* ExclamationEqualsToken */) {
|
if (op === 28 /* EqualsEqualsToken */ || op == 29 /* ExclamationEqualsToken */) {
|
||||||
report(node, "Use '===' and '!=='.");
|
report(node, "Use '===' and '!=='.");
|
||||||
|
|
149
tests/baselines/reference/typeGuardFunction.js
Normal file
149
tests/baselines/reference/typeGuardFunction.js
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
//// [typeGuardFunction.ts]
|
||||||
|
|
||||||
|
class A {
|
||||||
|
propA: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
propB: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
propC: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isA(p1: any): p1 is A;
|
||||||
|
declare function isB(p1: any): p1 is B;
|
||||||
|
declare function isC(p1: any): p1 is C;
|
||||||
|
|
||||||
|
declare function retC(): C;
|
||||||
|
|
||||||
|
var a: A;
|
||||||
|
var b: B;
|
||||||
|
|
||||||
|
// Basic
|
||||||
|
if (isC(a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub type
|
||||||
|
var subType: C;
|
||||||
|
if(isA(subType)) {
|
||||||
|
subType.propC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union type
|
||||||
|
var union: A | B;
|
||||||
|
if(isA(union)) {
|
||||||
|
union.propA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call signature
|
||||||
|
interface I1 {
|
||||||
|
(p1: A): p1 is C;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The parameter index and argument index for the type guard target is matching.
|
||||||
|
// The type predicate type is assignable to the parameter type.
|
||||||
|
declare function isC_multipleParams(p1, p2): p1 is C;
|
||||||
|
if (isC_multipleParams(a, 0)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
var obj: {
|
||||||
|
func1(p1: A): p1 is C;
|
||||||
|
}
|
||||||
|
class D {
|
||||||
|
method1(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrow function
|
||||||
|
let f1 = (p1: A): p1 is C => false;
|
||||||
|
|
||||||
|
// Function type
|
||||||
|
declare function f2(p1: (p1: A) => p1 is C);
|
||||||
|
|
||||||
|
// Function expressions
|
||||||
|
f2(function(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Evaluations are asssignable to boolean.
|
||||||
|
declare function acceptingBoolean(a: boolean);
|
||||||
|
acceptingBoolean(isA(a));
|
||||||
|
|
||||||
|
// Type predicates with different parameter name.
|
||||||
|
declare function acceptingTypeGuardFunction(p1: (item) => item is A);
|
||||||
|
acceptingTypeGuardFunction(isA);
|
||||||
|
|
||||||
|
// Binary expressions
|
||||||
|
let union2: C | B;
|
||||||
|
let union3: boolean | B = isA(union2) || union2;
|
||||||
|
|
||||||
|
//// [typeGuardFunction.js]
|
||||||
|
var __extends = (this && this.__extends) || function (d, b) {
|
||||||
|
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
__.prototype = b.prototype;
|
||||||
|
d.prototype = new __();
|
||||||
|
};
|
||||||
|
var A = (function () {
|
||||||
|
function A() {
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
})();
|
||||||
|
var B = (function () {
|
||||||
|
function B() {
|
||||||
|
}
|
||||||
|
return B;
|
||||||
|
})();
|
||||||
|
var C = (function (_super) {
|
||||||
|
__extends(C, _super);
|
||||||
|
function C() {
|
||||||
|
_super.apply(this, arguments);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
})(A);
|
||||||
|
var a;
|
||||||
|
var b;
|
||||||
|
// Basic
|
||||||
|
if (isC(a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
// Sub type
|
||||||
|
var subType;
|
||||||
|
if (isA(subType)) {
|
||||||
|
subType.propC;
|
||||||
|
}
|
||||||
|
// Union type
|
||||||
|
var union;
|
||||||
|
if (isA(union)) {
|
||||||
|
union.propA;
|
||||||
|
}
|
||||||
|
if (isC_multipleParams(a, 0)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
// Methods
|
||||||
|
var obj;
|
||||||
|
var D = (function () {
|
||||||
|
function D() {
|
||||||
|
}
|
||||||
|
D.prototype.method1 = function (p1) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
return D;
|
||||||
|
})();
|
||||||
|
// Arrow function
|
||||||
|
var f1 = function (p1) { return false; };
|
||||||
|
// Function expressions
|
||||||
|
f2(function (p1) {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
acceptingBoolean(isA(a));
|
||||||
|
acceptingTypeGuardFunction(isA);
|
||||||
|
// Binary expressions
|
||||||
|
var union2;
|
||||||
|
var union3 = isA(union2) || union2;
|
203
tests/baselines/reference/typeGuardFunction.symbols
Normal file
203
tests/baselines/reference/typeGuardFunction.symbols
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts ===
|
||||||
|
|
||||||
|
class A {
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
|
||||||
|
propA: number;
|
||||||
|
>propA : Symbol(propA, Decl(typeGuardFunction.ts, 1, 9))
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1))
|
||||||
|
|
||||||
|
propB: number;
|
||||||
|
>propB : Symbol(propB, Decl(typeGuardFunction.ts, 5, 9))
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
|
||||||
|
propC: number;
|
||||||
|
>propC : Symbol(propC, Decl(typeGuardFunction.ts, 9, 19))
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isA(p1: any): p1 is A;
|
||||||
|
>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 13, 21))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
|
||||||
|
declare function isB(p1: any): p1 is B;
|
||||||
|
>isB : Symbol(isB, Decl(typeGuardFunction.ts, 13, 39))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 14, 21))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1))
|
||||||
|
|
||||||
|
declare function isC(p1: any): p1 is C;
|
||||||
|
>isC : Symbol(isC, Decl(typeGuardFunction.ts, 14, 39))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 15, 21))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
declare function retC(): C;
|
||||||
|
>retC : Symbol(retC, Decl(typeGuardFunction.ts, 15, 39))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
var a: A;
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
|
||||||
|
var b: B;
|
||||||
|
>b : Symbol(b, Decl(typeGuardFunction.ts, 20, 3))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1))
|
||||||
|
|
||||||
|
// Basic
|
||||||
|
if (isC(a)) {
|
||||||
|
>isC : Symbol(isC, Decl(typeGuardFunction.ts, 14, 39))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3))
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3))
|
||||||
|
>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub type
|
||||||
|
var subType: C;
|
||||||
|
>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
if(isA(subType)) {
|
||||||
|
>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1))
|
||||||
|
>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3))
|
||||||
|
|
||||||
|
subType.propC;
|
||||||
|
>subType.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19))
|
||||||
|
>subType : Symbol(subType, Decl(typeGuardFunction.ts, 28, 3))
|
||||||
|
>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union type
|
||||||
|
var union: A | B;
|
||||||
|
>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1))
|
||||||
|
|
||||||
|
if(isA(union)) {
|
||||||
|
>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1))
|
||||||
|
>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3))
|
||||||
|
|
||||||
|
union.propA;
|
||||||
|
>union.propA : Symbol(A.propA, Decl(typeGuardFunction.ts, 1, 9))
|
||||||
|
>union : Symbol(union, Decl(typeGuardFunction.ts, 34, 3))
|
||||||
|
>propA : Symbol(A.propA, Decl(typeGuardFunction.ts, 1, 9))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call signature
|
||||||
|
interface I1 {
|
||||||
|
>I1 : Symbol(I1, Decl(typeGuardFunction.ts, 37, 1))
|
||||||
|
|
||||||
|
(p1: A): p1 is C;
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 41, 5))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
// The parameter index and argument index for the type guard target is matching.
|
||||||
|
// The type predicate type is assignable to the parameter type.
|
||||||
|
declare function isC_multipleParams(p1, p2): p1 is C;
|
||||||
|
>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 42, 1))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 46, 36))
|
||||||
|
>p2 : Symbol(p2, Decl(typeGuardFunction.ts, 46, 39))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
if (isC_multipleParams(a, 0)) {
|
||||||
|
>isC_multipleParams : Symbol(isC_multipleParams, Decl(typeGuardFunction.ts, 42, 1))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3))
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3))
|
||||||
|
>propC : Symbol(C.propC, Decl(typeGuardFunction.ts, 9, 19))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
var obj: {
|
||||||
|
>obj : Symbol(obj, Decl(typeGuardFunction.ts, 52, 3))
|
||||||
|
|
||||||
|
func1(p1: A): p1 is C;
|
||||||
|
>func1 : Symbol(func1, Decl(typeGuardFunction.ts, 52, 10))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 53, 10))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
}
|
||||||
|
class D {
|
||||||
|
>D : Symbol(D, Decl(typeGuardFunction.ts, 54, 1))
|
||||||
|
|
||||||
|
method1(p1: A): p1 is C {
|
||||||
|
>method1 : Symbol(method1, Decl(typeGuardFunction.ts, 55, 9))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 56, 12))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrow function
|
||||||
|
let f1 = (p1: A): p1 is C => false;
|
||||||
|
>f1 : Symbol(f1, Decl(typeGuardFunction.ts, 62, 3))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 62, 10))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
// Function type
|
||||||
|
declare function f2(p1: (p1: A) => p1 is C);
|
||||||
|
>f2 : Symbol(f2, Decl(typeGuardFunction.ts, 62, 35))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 65, 20))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 65, 25))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
// Function expressions
|
||||||
|
f2(function(p1: A): p1 is C {
|
||||||
|
>f2 : Symbol(f2, Decl(typeGuardFunction.ts, 62, 35))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 68, 12))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Evaluations are asssignable to boolean.
|
||||||
|
declare function acceptingBoolean(a: boolean);
|
||||||
|
>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 70, 3))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunction.ts, 73, 34))
|
||||||
|
|
||||||
|
acceptingBoolean(isA(a));
|
||||||
|
>acceptingBoolean : Symbol(acceptingBoolean, Decl(typeGuardFunction.ts, 70, 3))
|
||||||
|
>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunction.ts, 19, 3))
|
||||||
|
|
||||||
|
// Type predicates with different parameter name.
|
||||||
|
declare function acceptingTypeGuardFunction(p1: (item) => item is A);
|
||||||
|
>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 74, 25))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunction.ts, 77, 44))
|
||||||
|
>item : Symbol(item, Decl(typeGuardFunction.ts, 77, 49))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunction.ts, 0, 0))
|
||||||
|
|
||||||
|
acceptingTypeGuardFunction(isA);
|
||||||
|
>acceptingTypeGuardFunction : Symbol(acceptingTypeGuardFunction, Decl(typeGuardFunction.ts, 74, 25))
|
||||||
|
>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1))
|
||||||
|
|
||||||
|
// Binary expressions
|
||||||
|
let union2: C | B;
|
||||||
|
>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunction.ts, 7, 1))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1))
|
||||||
|
|
||||||
|
let union3: boolean | B = isA(union2) || union2;
|
||||||
|
>union3 : Symbol(union3, Decl(typeGuardFunction.ts, 82, 3))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunction.ts, 3, 1))
|
||||||
|
>isA : Symbol(isA, Decl(typeGuardFunction.ts, 11, 1))
|
||||||
|
>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3))
|
||||||
|
>union2 : Symbol(union2, Decl(typeGuardFunction.ts, 81, 3))
|
||||||
|
|
231
tests/baselines/reference/typeGuardFunction.types
Normal file
231
tests/baselines/reference/typeGuardFunction.types
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardFunction.ts ===
|
||||||
|
|
||||||
|
class A {
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
propA: number;
|
||||||
|
>propA : number
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
>B : B
|
||||||
|
|
||||||
|
propB: number;
|
||||||
|
>propB : number
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
>C : C
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
propC: number;
|
||||||
|
>propC : number
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isA(p1: any): p1 is A;
|
||||||
|
>isA : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
declare function isB(p1: any): p1 is B;
|
||||||
|
>isB : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>B : B
|
||||||
|
|
||||||
|
declare function isC(p1: any): p1 is C;
|
||||||
|
>isC : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
declare function retC(): C;
|
||||||
|
>retC : () => C
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
var a: A;
|
||||||
|
>a : A
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
var b: B;
|
||||||
|
>b : B
|
||||||
|
>B : B
|
||||||
|
|
||||||
|
// Basic
|
||||||
|
if (isC(a)) {
|
||||||
|
>isC(a) : boolean
|
||||||
|
>isC : (p1: any) => boolean
|
||||||
|
>a : A
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : number
|
||||||
|
>a : C
|
||||||
|
>propC : number
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub type
|
||||||
|
var subType: C;
|
||||||
|
>subType : C
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
if(isA(subType)) {
|
||||||
|
>isA(subType) : boolean
|
||||||
|
>isA : (p1: any) => boolean
|
||||||
|
>subType : C
|
||||||
|
|
||||||
|
subType.propC;
|
||||||
|
>subType.propC : number
|
||||||
|
>subType : C
|
||||||
|
>propC : number
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union type
|
||||||
|
var union: A | B;
|
||||||
|
>union : A | B
|
||||||
|
>A : A
|
||||||
|
>B : B
|
||||||
|
|
||||||
|
if(isA(union)) {
|
||||||
|
>isA(union) : boolean
|
||||||
|
>isA : (p1: any) => boolean
|
||||||
|
>union : A | B
|
||||||
|
|
||||||
|
union.propA;
|
||||||
|
>union.propA : number
|
||||||
|
>union : A
|
||||||
|
>propA : number
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call signature
|
||||||
|
interface I1 {
|
||||||
|
>I1 : I1
|
||||||
|
|
||||||
|
(p1: A): p1 is C;
|
||||||
|
>p1 : A
|
||||||
|
>A : A
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
}
|
||||||
|
|
||||||
|
// The parameter index and argument index for the type guard target is matching.
|
||||||
|
// The type predicate type is assignable to the parameter type.
|
||||||
|
declare function isC_multipleParams(p1, p2): p1 is C;
|
||||||
|
>isC_multipleParams : (p1: any, p2: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p2 : any
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
if (isC_multipleParams(a, 0)) {
|
||||||
|
>isC_multipleParams(a, 0) : boolean
|
||||||
|
>isC_multipleParams : (p1: any, p2: any) => boolean
|
||||||
|
>a : A
|
||||||
|
>0 : number
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : number
|
||||||
|
>a : C
|
||||||
|
>propC : number
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
var obj: {
|
||||||
|
>obj : { func1(p1: A): boolean; }
|
||||||
|
|
||||||
|
func1(p1: A): p1 is C;
|
||||||
|
>func1 : (p1: A) => boolean
|
||||||
|
>p1 : A
|
||||||
|
>A : A
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
}
|
||||||
|
class D {
|
||||||
|
>D : D
|
||||||
|
|
||||||
|
method1(p1: A): p1 is C {
|
||||||
|
>method1 : (p1: A) => boolean
|
||||||
|
>p1 : A
|
||||||
|
>A : A
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrow function
|
||||||
|
let f1 = (p1: A): p1 is C => false;
|
||||||
|
>f1 : (p1: A) => boolean
|
||||||
|
>(p1: A): p1 is C => false : (p1: A) => boolean
|
||||||
|
>p1 : A
|
||||||
|
>A : A
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
>false : boolean
|
||||||
|
|
||||||
|
// Function type
|
||||||
|
declare function f2(p1: (p1: A) => p1 is C);
|
||||||
|
>f2 : (p1: (p1: A) => boolean) => any
|
||||||
|
>p1 : (p1: A) => boolean
|
||||||
|
>p1 : A
|
||||||
|
>A : A
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
// Function expressions
|
||||||
|
f2(function(p1: A): p1 is C {
|
||||||
|
>f2(function(p1: A): p1 is C { return true;}) : any
|
||||||
|
>f2 : (p1: (p1: A) => boolean) => any
|
||||||
|
>function(p1: A): p1 is C { return true;} : (p1: A) => boolean
|
||||||
|
>p1 : A
|
||||||
|
>A : A
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Evaluations are asssignable to boolean.
|
||||||
|
declare function acceptingBoolean(a: boolean);
|
||||||
|
>acceptingBoolean : (a: boolean) => any
|
||||||
|
>a : boolean
|
||||||
|
|
||||||
|
acceptingBoolean(isA(a));
|
||||||
|
>acceptingBoolean(isA(a)) : any
|
||||||
|
>acceptingBoolean : (a: boolean) => any
|
||||||
|
>isA(a) : boolean
|
||||||
|
>isA : (p1: any) => boolean
|
||||||
|
>a : A
|
||||||
|
|
||||||
|
// Type predicates with different parameter name.
|
||||||
|
declare function acceptingTypeGuardFunction(p1: (item) => item is A);
|
||||||
|
>acceptingTypeGuardFunction : (p1: (item: any) => boolean) => any
|
||||||
|
>p1 : (item: any) => boolean
|
||||||
|
>item : any
|
||||||
|
>item : any
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
acceptingTypeGuardFunction(isA);
|
||||||
|
>acceptingTypeGuardFunction(isA) : any
|
||||||
|
>acceptingTypeGuardFunction : (p1: (item: any) => boolean) => any
|
||||||
|
>isA : (p1: any) => boolean
|
||||||
|
|
||||||
|
// Binary expressions
|
||||||
|
let union2: C | B;
|
||||||
|
>union2 : B | C
|
||||||
|
>C : C
|
||||||
|
>B : B
|
||||||
|
|
||||||
|
let union3: boolean | B = isA(union2) || union2;
|
||||||
|
>union3 : boolean | B
|
||||||
|
>B : B
|
||||||
|
>isA(union2) || union2 : boolean | B
|
||||||
|
>isA(union2) : boolean
|
||||||
|
>isA : (p1: any) => boolean
|
||||||
|
>union2 : B | C
|
||||||
|
>union2 : B
|
||||||
|
|
240
tests/baselines/reference/typeGuardFunctionErrors.errors.txt
Normal file
240
tests/baselines/reference/typeGuardFunctionErrors.errors.txt
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(15,12): error TS2322: Type 'string' is not assignable to type 'boolean'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(22,33): error TS2304: Cannot find name 'x'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(26,10): error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(27,5): error TS1131: Property or signature expected.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(28,1): error TS1128: Declaration or statement expected.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,38): error TS1225: Cannot find parameter 'x'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(34,51): error TS2322: Type 'B' is not assignable to type 'A'.
|
||||||
|
Property 'propA' is missing in type 'B'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(38,56): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(42,56): error TS2322: Type 'T[]' is not assignable to type 'string'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(56,7): error TS2339: Property 'propB' does not exist on type 'A'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(61,7): error TS2339: Property 'propB' does not exist on type 'A'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(66,7): error TS2339: Property 'propB' does not exist on type 'A'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(71,46): error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'.
|
||||||
|
Type predicate 'p1 is C' is not assignable to 'p1 is B'.
|
||||||
|
Type 'C' is not assignable to type 'B'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(75,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||||
|
Signature '(p1: any, p2: any): boolean' must have a type predicate.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(81,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||||
|
Type predicate 'p2 is A' is not assignable to 'p1 is A'.
|
||||||
|
Parameter 'p2' is not in the same position as parameter 'p1'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(87,1): error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(92,9): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(93,16): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(94,20): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(100,25): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(101,16): error TS2409: Return type of constructor signature must be assignable to the instance type of the class
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(103,20): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(106,20): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(107,16): error TS2408: Setters cannot return a value.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(112,18): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(116,22): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(120,20): error TS1229: A type predicate cannot reference a rest parameter.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(125,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(129,34): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||||
|
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(133,39): error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts (30 errors) ====
|
||||||
|
|
||||||
|
class A {
|
||||||
|
propA: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
propB: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
propC: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasANonBooleanReturnStatement(x): x is A {
|
||||||
|
return '';
|
||||||
|
~~
|
||||||
|
!!! error TS2322: Type 'string' is not assignable to type 'boolean'.
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMissingIsKeyword(): x {
|
||||||
|
~
|
||||||
|
!!! error TS2304: Cannot find name 'x'.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMissingTypeInTypeGuardType(x): x is {
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||||
|
return true;
|
||||||
|
~~~~~~
|
||||||
|
!!! error TS1131: Property or signature expected.
|
||||||
|
}
|
||||||
|
~
|
||||||
|
!!! error TS1128: Declaration or statement expected.
|
||||||
|
|
||||||
|
function hasNonMatchingParameter(y): x is A {
|
||||||
|
~
|
||||||
|
!!! error TS1225: Cannot find parameter 'x'.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameterType1(x: A): x is B {
|
||||||
|
~
|
||||||
|
!!! error TS2322: Type 'B' is not assignable to type 'A'.
|
||||||
|
!!! error TS2322: Property 'propA' is missing in type 'B'.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameterType2(x: string): x is number {
|
||||||
|
~~~~~~
|
||||||
|
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMathcingGenericType<T>(a: string): a is T[] {
|
||||||
|
~~~
|
||||||
|
!!! error TS2322: Type 'T[]' is not assignable to type 'string'.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let a: A;
|
||||||
|
let b: B;
|
||||||
|
|
||||||
|
declare function isB(p1): p1 is B;
|
||||||
|
declare function isC(p1): p1 is C;
|
||||||
|
declare function funA(p1: any, p2: any): p1 is B;
|
||||||
|
declare function hasNoTypeGuard(x);
|
||||||
|
|
||||||
|
// Passed argument is not the same as the one being guarded.
|
||||||
|
if (isB(b)) {
|
||||||
|
a.propB;
|
||||||
|
~~~~~
|
||||||
|
!!! error TS2339: Property 'propB' does not exist on type 'A'.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter index and argument index for the type guard target is not matching.
|
||||||
|
if (funA(0, a)) {
|
||||||
|
a.propB; // Error
|
||||||
|
~~~~~
|
||||||
|
!!! error TS2339: Property 'propB' does not exist on type 'A'.
|
||||||
|
}
|
||||||
|
|
||||||
|
// No type guard in if statement
|
||||||
|
if (hasNoTypeGuard(a)) {
|
||||||
|
a.propB;
|
||||||
|
~~~~~
|
||||||
|
!!! error TS2339: Property 'propB' does not exist on type 'A'.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type predicate type is not assignable
|
||||||
|
declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B);
|
||||||
|
acceptingDifferentSignatureTypeGuardFunction(isC);
|
||||||
|
~~~
|
||||||
|
!!! error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'.
|
||||||
|
!!! error TS2345: Type predicate 'p1 is C' is not assignable to 'p1 is B'.
|
||||||
|
!!! error TS2345: Type 'C' is not assignable to type 'B'.
|
||||||
|
|
||||||
|
// Boolean not assignable to type guard
|
||||||
|
var assign1: (p1, p2) => p1 is A;
|
||||||
|
assign1 = function(p1, p2): boolean {
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||||
|
!!! error TS2322: Signature '(p1: any, p2: any): boolean' must have a type predicate.
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must have matching parameter index
|
||||||
|
var assign2: (p1, p2) => p1 is A;
|
||||||
|
assign2 = function(p1, p2): p2 is A {
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||||
|
!!! error TS2322: Type predicate 'p2 is A' is not assignable to 'p1 is A'.
|
||||||
|
!!! error TS2322: Parameter 'p2' is not in the same position as parameter 'p1'.
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// No matching signature
|
||||||
|
var assign3: (p1, p2) => p1 is A;
|
||||||
|
assign3 = function(p1, p2, p3): p1 is A {
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS2322: Type '(p1: any, p2: any, p3: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type predicates in non-return type positions
|
||||||
|
var b1: b is A;
|
||||||
|
~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
function b2(a: b is A) {};
|
||||||
|
~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
function b3(): A | b is A {
|
||||||
|
~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-compatiable type predicate positions for signature declarations
|
||||||
|
class D {
|
||||||
|
constructor(p1: A): p1 is C {
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
return true;
|
||||||
|
~~~~
|
||||||
|
!!! error TS2409: Return type of constructor signature must be assignable to the instance type of the class
|
||||||
|
}
|
||||||
|
get m1(p1: A): p1 is C {
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
set m2(p1: A): p1 is C {
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
return true;
|
||||||
|
~~~~
|
||||||
|
!!! error TS2408: Setters cannot return a value.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I1 {
|
||||||
|
new (p1: A): p1 is C;
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I2 {
|
||||||
|
[index: number]: p1 is C;
|
||||||
|
~~~~~~~
|
||||||
|
!!! error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference to rest parameter
|
||||||
|
function b4(...a): a is A {
|
||||||
|
~
|
||||||
|
!!! error TS1229: A type predicate cannot reference a rest parameter.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference to binding pattern
|
||||||
|
function b5({a, b, p1}, p2, p3): p1 is A {
|
||||||
|
~~
|
||||||
|
!!! error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function b6([a, b, p1], p2, p3): p1 is A {
|
||||||
|
~~
|
||||||
|
!!! error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function b7({a, b, c: {p1}}, p2, p3): p1 is A {
|
||||||
|
~~
|
||||||
|
!!! error TS1230: A type predicate cannot reference element 'p1' in a binding pattern.
|
||||||
|
return true;
|
||||||
|
}
|
263
tests/baselines/reference/typeGuardFunctionErrors.js
Normal file
263
tests/baselines/reference/typeGuardFunctionErrors.js
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
//// [typeGuardFunctionErrors.ts]
|
||||||
|
|
||||||
|
class A {
|
||||||
|
propA: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
propB: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
propC: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasANonBooleanReturnStatement(x): x is A {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMissingIsKeyword(): x {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMissingTypeInTypeGuardType(x): x is {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameter(y): x is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameterType1(x: A): x is B {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameterType2(x: string): x is number {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMathcingGenericType<T>(a: string): a is T[] {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let a: A;
|
||||||
|
let b: B;
|
||||||
|
|
||||||
|
declare function isB(p1): p1 is B;
|
||||||
|
declare function isC(p1): p1 is C;
|
||||||
|
declare function funA(p1: any, p2: any): p1 is B;
|
||||||
|
declare function hasNoTypeGuard(x);
|
||||||
|
|
||||||
|
// Passed argument is not the same as the one being guarded.
|
||||||
|
if (isB(b)) {
|
||||||
|
a.propB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter index and argument index for the type guard target is not matching.
|
||||||
|
if (funA(0, a)) {
|
||||||
|
a.propB; // Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// No type guard in if statement
|
||||||
|
if (hasNoTypeGuard(a)) {
|
||||||
|
a.propB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type predicate type is not assignable
|
||||||
|
declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B);
|
||||||
|
acceptingDifferentSignatureTypeGuardFunction(isC);
|
||||||
|
|
||||||
|
// Boolean not assignable to type guard
|
||||||
|
var assign1: (p1, p2) => p1 is A;
|
||||||
|
assign1 = function(p1, p2): boolean {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must have matching parameter index
|
||||||
|
var assign2: (p1, p2) => p1 is A;
|
||||||
|
assign2 = function(p1, p2): p2 is A {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// No matching signature
|
||||||
|
var assign3: (p1, p2) => p1 is A;
|
||||||
|
assign3 = function(p1, p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type predicates in non-return type positions
|
||||||
|
var b1: b is A;
|
||||||
|
function b2(a: b is A) {};
|
||||||
|
function b3(): A | b is A {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-compatiable type predicate positions for signature declarations
|
||||||
|
class D {
|
||||||
|
constructor(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
get m1(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
set m2(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I1 {
|
||||||
|
new (p1: A): p1 is C;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I2 {
|
||||||
|
[index: number]: p1 is C;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference to rest parameter
|
||||||
|
function b4(...a): a is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference to binding pattern
|
||||||
|
function b5({a, b, p1}, p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function b6([a, b, p1], p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function b7({a, b, c: {p1}}, p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// [typeGuardFunctionErrors.js]
|
||||||
|
var __extends = (this && this.__extends) || function (d, b) {
|
||||||
|
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
__.prototype = b.prototype;
|
||||||
|
d.prototype = new __();
|
||||||
|
};
|
||||||
|
var A = (function () {
|
||||||
|
function A() {
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
})();
|
||||||
|
var B = (function () {
|
||||||
|
function B() {
|
||||||
|
}
|
||||||
|
return B;
|
||||||
|
})();
|
||||||
|
var C = (function (_super) {
|
||||||
|
__extends(C, _super);
|
||||||
|
function C() {
|
||||||
|
_super.apply(this, arguments);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
})(A);
|
||||||
|
function hasANonBooleanReturnStatement(x) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
function hasTypeGuardTypeInsideTypeGuardType(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function hasMissingIsKeyword() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
function hasNonMatchingParameter(y) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function hasNonMatchingParameterType1(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function hasNonMatchingParameterType2(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function hasNonMathcingGenericType(a) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var a;
|
||||||
|
var b;
|
||||||
|
// Passed argument is not the same as the one being guarded.
|
||||||
|
if (isB(b)) {
|
||||||
|
a.propB;
|
||||||
|
}
|
||||||
|
// Parameter index and argument index for the type guard target is not matching.
|
||||||
|
if (funA(0, a)) {
|
||||||
|
a.propB; // Error
|
||||||
|
}
|
||||||
|
// No type guard in if statement
|
||||||
|
if (hasNoTypeGuard(a)) {
|
||||||
|
a.propB;
|
||||||
|
}
|
||||||
|
acceptingDifferentSignatureTypeGuardFunction(isC);
|
||||||
|
// Boolean not assignable to type guard
|
||||||
|
var assign1;
|
||||||
|
assign1 = function (p1, p2) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// Must have matching parameter index
|
||||||
|
var assign2;
|
||||||
|
assign2 = function (p1, p2) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// No matching signature
|
||||||
|
var assign3;
|
||||||
|
assign3 = function (p1, p2, p3) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
// Type predicates in non-return type positions
|
||||||
|
var b1;
|
||||||
|
function b2(a) { }
|
||||||
|
;
|
||||||
|
function b3() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
// Non-compatiable type predicate positions for signature declarations
|
||||||
|
var D = (function () {
|
||||||
|
function D(p1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Object.defineProperty(D.prototype, "m1", {
|
||||||
|
get: function (p1) {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
Object.defineProperty(D.prototype, "m2", {
|
||||||
|
set: function (p1) {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
|
return D;
|
||||||
|
})();
|
||||||
|
// Reference to rest parameter
|
||||||
|
function b4() {
|
||||||
|
var a = [];
|
||||||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||||||
|
a[_i - 0] = arguments[_i];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Reference to binding pattern
|
||||||
|
function b5(_a, p2, p3) {
|
||||||
|
var a = _a.a, b = _a.b, p1 = _a.p1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function b6(_a, p2, p3) {
|
||||||
|
var a = _a[0], b = _a[1], p1 = _a[2];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function b7(_a, p2, p3) {
|
||||||
|
var a = _a.a, b = _a.b, p1 = _a.c.p1;
|
||||||
|
return true;
|
||||||
|
}
|
69
tests/baselines/reference/typeGuardFunctionGenerics.js
Normal file
69
tests/baselines/reference/typeGuardFunctionGenerics.js
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//// [typeGuardFunctionGenerics.ts]
|
||||||
|
|
||||||
|
class A {
|
||||||
|
propA: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
propB: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
propC: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isB(p1): p1 is B;
|
||||||
|
declare function isC(p1): p1 is C;
|
||||||
|
declare function retC(x): C;
|
||||||
|
|
||||||
|
declare function funA<T>(p1: (p1) => T): T;
|
||||||
|
declare function funB<T>(p1: (p1) => T, p2: any): p2 is T;
|
||||||
|
declare function funC<T>(p1: (p1) => p1 is T): T;
|
||||||
|
declare function funD<T>(p1: (p1) => p1 is T, p2: any): p2 is T;
|
||||||
|
declare function funE<T, U>(p1: (p1) => p1 is T, p2: U): T;
|
||||||
|
|
||||||
|
let a: A;
|
||||||
|
let test1: boolean = funA(isB);
|
||||||
|
if (funB(retC, a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
let test2: B = funC(isB);
|
||||||
|
if (funD(isC, a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
let test3: B = funE(isB, 1);
|
||||||
|
|
||||||
|
//// [typeGuardFunctionGenerics.js]
|
||||||
|
var __extends = (this && this.__extends) || function (d, b) {
|
||||||
|
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
__.prototype = b.prototype;
|
||||||
|
d.prototype = new __();
|
||||||
|
};
|
||||||
|
var A = (function () {
|
||||||
|
function A() {
|
||||||
|
}
|
||||||
|
return A;
|
||||||
|
})();
|
||||||
|
var B = (function () {
|
||||||
|
function B() {
|
||||||
|
}
|
||||||
|
return B;
|
||||||
|
})();
|
||||||
|
var C = (function (_super) {
|
||||||
|
__extends(C, _super);
|
||||||
|
function C() {
|
||||||
|
_super.apply(this, arguments);
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
})(A);
|
||||||
|
var a;
|
||||||
|
var test1 = funA(isB);
|
||||||
|
if (funB(retC, a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
var test2 = funC(isB);
|
||||||
|
if (funD(isC, a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
var test3 = funE(isB, 1);
|
125
tests/baselines/reference/typeGuardFunctionGenerics.symbols
Normal file
125
tests/baselines/reference/typeGuardFunctionGenerics.symbols
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts ===
|
||||||
|
|
||||||
|
class A {
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0))
|
||||||
|
|
||||||
|
propA: number;
|
||||||
|
>propA : Symbol(propA, Decl(typeGuardFunctionGenerics.ts, 1, 9))
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1))
|
||||||
|
|
||||||
|
propB: number;
|
||||||
|
>propB : Symbol(propB, Decl(typeGuardFunctionGenerics.ts, 5, 9))
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0))
|
||||||
|
|
||||||
|
propC: number;
|
||||||
|
>propC : Symbol(propC, Decl(typeGuardFunctionGenerics.ts, 9, 19))
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isB(p1): p1 is B;
|
||||||
|
>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 13, 21))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1))
|
||||||
|
|
||||||
|
declare function isC(p1): p1 is C;
|
||||||
|
>isC : Symbol(isC, Decl(typeGuardFunctionGenerics.ts, 13, 34))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 14, 21))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1))
|
||||||
|
|
||||||
|
declare function retC(x): C;
|
||||||
|
>retC : Symbol(retC, Decl(typeGuardFunctionGenerics.ts, 14, 34))
|
||||||
|
>x : Symbol(x, Decl(typeGuardFunctionGenerics.ts, 15, 22))
|
||||||
|
>C : Symbol(C, Decl(typeGuardFunctionGenerics.ts, 7, 1))
|
||||||
|
|
||||||
|
declare function funA<T>(p1: (p1) => T): T;
|
||||||
|
>funA : Symbol(funA, Decl(typeGuardFunctionGenerics.ts, 15, 28))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 17, 25))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 17, 30))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 17, 22))
|
||||||
|
|
||||||
|
declare function funB<T>(p1: (p1) => T, p2: any): p2 is T;
|
||||||
|
>funB : Symbol(funB, Decl(typeGuardFunctionGenerics.ts, 17, 43))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 18, 25))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 18, 30))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22))
|
||||||
|
>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 18, 39))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 18, 22))
|
||||||
|
|
||||||
|
declare function funC<T>(p1: (p1) => p1 is T): T;
|
||||||
|
>funC : Symbol(funC, Decl(typeGuardFunctionGenerics.ts, 18, 58))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 19, 25))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 19, 30))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 19, 22))
|
||||||
|
|
||||||
|
declare function funD<T>(p1: (p1) => p1 is T, p2: any): p2 is T;
|
||||||
|
>funD : Symbol(funD, Decl(typeGuardFunctionGenerics.ts, 19, 49))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 20, 25))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 20, 30))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22))
|
||||||
|
>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 20, 45))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 20, 22))
|
||||||
|
|
||||||
|
declare function funE<T, U>(p1: (p1) => p1 is T, p2: U): T;
|
||||||
|
>funE : Symbol(funE, Decl(typeGuardFunctionGenerics.ts, 20, 64))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22))
|
||||||
|
>U : Symbol(U, Decl(typeGuardFunctionGenerics.ts, 21, 24))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 21, 28))
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardFunctionGenerics.ts, 21, 33))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22))
|
||||||
|
>p2 : Symbol(p2, Decl(typeGuardFunctionGenerics.ts, 21, 48))
|
||||||
|
>U : Symbol(U, Decl(typeGuardFunctionGenerics.ts, 21, 24))
|
||||||
|
>T : Symbol(T, Decl(typeGuardFunctionGenerics.ts, 21, 22))
|
||||||
|
|
||||||
|
let a: A;
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3))
|
||||||
|
>A : Symbol(A, Decl(typeGuardFunctionGenerics.ts, 0, 0))
|
||||||
|
|
||||||
|
let test1: boolean = funA(isB);
|
||||||
|
>test1 : Symbol(test1, Decl(typeGuardFunctionGenerics.ts, 24, 3))
|
||||||
|
>funA : Symbol(funA, Decl(typeGuardFunctionGenerics.ts, 15, 28))
|
||||||
|
>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1))
|
||||||
|
|
||||||
|
if (funB(retC, a)) {
|
||||||
|
>funB : Symbol(funB, Decl(typeGuardFunctionGenerics.ts, 17, 43))
|
||||||
|
>retC : Symbol(retC, Decl(typeGuardFunctionGenerics.ts, 14, 34))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3))
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3))
|
||||||
|
>propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19))
|
||||||
|
}
|
||||||
|
let test2: B = funC(isB);
|
||||||
|
>test2 : Symbol(test2, Decl(typeGuardFunctionGenerics.ts, 28, 3))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1))
|
||||||
|
>funC : Symbol(funC, Decl(typeGuardFunctionGenerics.ts, 18, 58))
|
||||||
|
>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1))
|
||||||
|
|
||||||
|
if (funD(isC, a)) {
|
||||||
|
>funD : Symbol(funD, Decl(typeGuardFunctionGenerics.ts, 19, 49))
|
||||||
|
>isC : Symbol(isC, Decl(typeGuardFunctionGenerics.ts, 13, 34))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3))
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19))
|
||||||
|
>a : Symbol(a, Decl(typeGuardFunctionGenerics.ts, 23, 3))
|
||||||
|
>propC : Symbol(C.propC, Decl(typeGuardFunctionGenerics.ts, 9, 19))
|
||||||
|
}
|
||||||
|
let test3: B = funE(isB, 1);
|
||||||
|
>test3 : Symbol(test3, Decl(typeGuardFunctionGenerics.ts, 32, 3))
|
||||||
|
>B : Symbol(B, Decl(typeGuardFunctionGenerics.ts, 3, 1))
|
||||||
|
>funE : Symbol(funE, Decl(typeGuardFunctionGenerics.ts, 20, 64))
|
||||||
|
>isB : Symbol(isB, Decl(typeGuardFunctionGenerics.ts, 11, 1))
|
||||||
|
|
138
tests/baselines/reference/typeGuardFunctionGenerics.types
Normal file
138
tests/baselines/reference/typeGuardFunctionGenerics.types
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardFunctionGenerics.ts ===
|
||||||
|
|
||||||
|
class A {
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
propA: number;
|
||||||
|
>propA : number
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
>B : B
|
||||||
|
|
||||||
|
propB: number;
|
||||||
|
>propB : number
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
>C : C
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
propC: number;
|
||||||
|
>propC : number
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isB(p1): p1 is B;
|
||||||
|
>isB : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>B : B
|
||||||
|
|
||||||
|
declare function isC(p1): p1 is C;
|
||||||
|
>isC : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
declare function retC(x): C;
|
||||||
|
>retC : (x: any) => C
|
||||||
|
>x : any
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
declare function funA<T>(p1: (p1) => T): T;
|
||||||
|
>funA : <T>(p1: (p1: any) => T) => T
|
||||||
|
>T : T
|
||||||
|
>p1 : (p1: any) => T
|
||||||
|
>p1 : any
|
||||||
|
>T : T
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
declare function funB<T>(p1: (p1) => T, p2: any): p2 is T;
|
||||||
|
>funB : <T>(p1: (p1: any) => T, p2: any) => boolean
|
||||||
|
>T : T
|
||||||
|
>p1 : (p1: any) => T
|
||||||
|
>p1 : any
|
||||||
|
>T : T
|
||||||
|
>p2 : any
|
||||||
|
>p2 : any
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
declare function funC<T>(p1: (p1) => p1 is T): T;
|
||||||
|
>funC : <T>(p1: (p1: any) => boolean) => T
|
||||||
|
>T : T
|
||||||
|
>p1 : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>T : T
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
declare function funD<T>(p1: (p1) => p1 is T, p2: any): p2 is T;
|
||||||
|
>funD : <T>(p1: (p1: any) => boolean, p2: any) => boolean
|
||||||
|
>T : T
|
||||||
|
>p1 : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>T : T
|
||||||
|
>p2 : any
|
||||||
|
>p2 : any
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
declare function funE<T, U>(p1: (p1) => p1 is T, p2: U): T;
|
||||||
|
>funE : <T, U>(p1: (p1: any) => boolean, p2: U) => T
|
||||||
|
>T : T
|
||||||
|
>U : U
|
||||||
|
>p1 : (p1: any) => boolean
|
||||||
|
>p1 : any
|
||||||
|
>p1 : any
|
||||||
|
>T : T
|
||||||
|
>p2 : U
|
||||||
|
>U : U
|
||||||
|
>T : T
|
||||||
|
|
||||||
|
let a: A;
|
||||||
|
>a : A
|
||||||
|
>A : A
|
||||||
|
|
||||||
|
let test1: boolean = funA(isB);
|
||||||
|
>test1 : boolean
|
||||||
|
>funA(isB) : boolean
|
||||||
|
>funA : <T>(p1: (p1: any) => T) => T
|
||||||
|
>isB : (p1: any) => boolean
|
||||||
|
|
||||||
|
if (funB(retC, a)) {
|
||||||
|
>funB(retC, a) : boolean
|
||||||
|
>funB : <T>(p1: (p1: any) => T, p2: any) => boolean
|
||||||
|
>retC : (x: any) => C
|
||||||
|
>a : A
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : number
|
||||||
|
>a : C
|
||||||
|
>propC : number
|
||||||
|
}
|
||||||
|
let test2: B = funC(isB);
|
||||||
|
>test2 : B
|
||||||
|
>B : B
|
||||||
|
>funC(isB) : B
|
||||||
|
>funC : <T>(p1: (p1: any) => boolean) => T
|
||||||
|
>isB : (p1: any) => boolean
|
||||||
|
|
||||||
|
if (funD(isC, a)) {
|
||||||
|
>funD(isC, a) : boolean
|
||||||
|
>funD : <T>(p1: (p1: any) => boolean, p2: any) => boolean
|
||||||
|
>isC : (p1: any) => boolean
|
||||||
|
>a : A
|
||||||
|
|
||||||
|
a.propC;
|
||||||
|
>a.propC : number
|
||||||
|
>a : C
|
||||||
|
>propC : number
|
||||||
|
}
|
||||||
|
let test3: B = funE(isB, 1);
|
||||||
|
>test3 : B
|
||||||
|
>B : B
|
||||||
|
>funE(isB, 1) : B
|
||||||
|
>funE : <T, U>(p1: (p1: any) => boolean, p2: U) => T
|
||||||
|
>isB : (p1: any) => boolean
|
||||||
|
>1 : number
|
||||||
|
|
85
tests/baselines/reference/typeGuardOfFormIsType.js
Normal file
85
tests/baselines/reference/typeGuardOfFormIsType.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
//// [typeGuardOfFormIsType.ts]
|
||||||
|
|
||||||
|
class C1 {
|
||||||
|
p1: string;
|
||||||
|
}
|
||||||
|
class C2 {
|
||||||
|
p2: number;
|
||||||
|
}
|
||||||
|
class D1 extends C1 {
|
||||||
|
p3: number;
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
var num: number;
|
||||||
|
var strOrNum: string | number;
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
||||||
|
|
||||||
|
//// [typeGuardOfFormIsType.js]
|
||||||
|
var __extends = (this && this.__extends) || function (d, b) {
|
||||||
|
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
__.prototype = b.prototype;
|
||||||
|
d.prototype = new __();
|
||||||
|
};
|
||||||
|
var C1 = (function () {
|
||||||
|
function C1() {
|
||||||
|
}
|
||||||
|
return C1;
|
||||||
|
})();
|
||||||
|
var C2 = (function () {
|
||||||
|
function C2() {
|
||||||
|
}
|
||||||
|
return C2;
|
||||||
|
})();
|
||||||
|
var D1 = (function (_super) {
|
||||||
|
__extends(D1, _super);
|
||||||
|
function D1() {
|
||||||
|
_super.apply(this, arguments);
|
||||||
|
}
|
||||||
|
return D1;
|
||||||
|
})(C1);
|
||||||
|
var str;
|
||||||
|
var num;
|
||||||
|
var strOrNum;
|
||||||
|
function isC1(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function isC2(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function isD1(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var c1Orc2;
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
var c2Ord1;
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
var r2 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
128
tests/baselines/reference/typeGuardOfFormIsType.symbols
Normal file
128
tests/baselines/reference/typeGuardOfFormIsType.symbols
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts ===
|
||||||
|
|
||||||
|
class C1 {
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0))
|
||||||
|
|
||||||
|
p1: string;
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardOfFormIsType.ts, 1, 10))
|
||||||
|
}
|
||||||
|
class C2 {
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1))
|
||||||
|
|
||||||
|
p2: number;
|
||||||
|
>p2 : Symbol(p2, Decl(typeGuardOfFormIsType.ts, 4, 10))
|
||||||
|
}
|
||||||
|
class D1 extends C1 {
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0))
|
||||||
|
|
||||||
|
p3: number;
|
||||||
|
>p3 : Symbol(p3, Decl(typeGuardOfFormIsType.ts, 7, 21))
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3))
|
||||||
|
|
||||||
|
var num: number;
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3))
|
||||||
|
|
||||||
|
var strOrNum: string | number;
|
||||||
|
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormIsType.ts, 12, 3))
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30))
|
||||||
|
>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 14, 14))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1))
|
||||||
|
>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 18, 14))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1))
|
||||||
|
>x : Symbol(x, Decl(typeGuardOfFormIsType.ts, 22, 14))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsType.ts, 0, 0))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1))
|
||||||
|
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3))
|
||||||
|
>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10))
|
||||||
|
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3))
|
||||||
|
>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>c1Orc2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10))
|
||||||
|
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10))
|
||||||
|
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>c1Orc2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsType.ts, 26, 3))
|
||||||
|
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21))
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1))
|
||||||
|
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3))
|
||||||
|
>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsType.ts, 16, 1))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>c2Ord1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsType.ts, 4, 10))
|
||||||
|
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsType.ts, 11, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>c2Ord1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsType.ts, 7, 21))
|
||||||
|
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsType.ts, 10, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsType.ts, 20, 1))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>c2Ord1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsType.ts, 1, 10))
|
||||||
|
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
||||||
|
>r2 : Symbol(r2, Decl(typeGuardOfFormIsType.ts, 36, 3))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsType.ts, 3, 1))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsType.ts, 6, 1))
|
||||||
|
>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsType.ts, 12, 30))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsType.ts, 32, 3))
|
||||||
|
|
157
tests/baselines/reference/typeGuardOfFormIsType.types
Normal file
157
tests/baselines/reference/typeGuardOfFormIsType.types
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsType.ts ===
|
||||||
|
|
||||||
|
class C1 {
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
p1: string;
|
||||||
|
>p1 : string
|
||||||
|
}
|
||||||
|
class C2 {
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
p2: number;
|
||||||
|
>p2 : number
|
||||||
|
}
|
||||||
|
class D1 extends C1 {
|
||||||
|
>D1 : D1
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
p3: number;
|
||||||
|
>p3 : number
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
>str : string
|
||||||
|
|
||||||
|
var num: number;
|
||||||
|
>num : number
|
||||||
|
|
||||||
|
var strOrNum: string | number;
|
||||||
|
>strOrNum : string | number
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
>isC1 : (x: any) => boolean
|
||||||
|
>x : any
|
||||||
|
>x : any
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
>isC2 : (x: any) => boolean
|
||||||
|
>x : any
|
||||||
|
>x : any
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>x : any
|
||||||
|
>x : any
|
||||||
|
>D1 : D1
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>C1 : C1
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
>str = isC1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>str : string
|
||||||
|
>isC1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>isC1(c1Orc2) : boolean
|
||||||
|
>isC1 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p1 : string
|
||||||
|
>c1Orc2 : C1
|
||||||
|
>p1 : string
|
||||||
|
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
>num = isC2(c1Orc2) && c1Orc2.p2 : number
|
||||||
|
>num : number
|
||||||
|
>isC2(c1Orc2) && c1Orc2.p2 : number
|
||||||
|
>isC2(c1Orc2) : boolean
|
||||||
|
>isC2 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p2 : number
|
||||||
|
>c1Orc2 : C2
|
||||||
|
>p2 : number
|
||||||
|
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
>str = isD1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>str : string
|
||||||
|
>isD1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>isD1(c1Orc2) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p1 : string
|
||||||
|
>c1Orc2 : D1
|
||||||
|
>p1 : string
|
||||||
|
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
>num = isD1(c1Orc2) && c1Orc2.p3 : number
|
||||||
|
>num : number
|
||||||
|
>isD1(c1Orc2) && c1Orc2.p3 : number
|
||||||
|
>isD1(c1Orc2) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p3 : number
|
||||||
|
>c1Orc2 : D1
|
||||||
|
>p3 : number
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>C2 : C2
|
||||||
|
>D1 : D1
|
||||||
|
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
>num = isC2(c2Ord1) && c2Ord1.p2 : number
|
||||||
|
>num : number
|
||||||
|
>isC2(c2Ord1) && c2Ord1.p2 : number
|
||||||
|
>isC2(c2Ord1) : boolean
|
||||||
|
>isC2 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1.p2 : number
|
||||||
|
>c2Ord1 : C2
|
||||||
|
>p2 : number
|
||||||
|
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
>num = isD1(c2Ord1) && c2Ord1.p3 : number
|
||||||
|
>num : number
|
||||||
|
>isD1(c2Ord1) && c2Ord1.p3 : number
|
||||||
|
>isD1(c2Ord1) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1.p3 : number
|
||||||
|
>c2Ord1 : D1
|
||||||
|
>p3 : number
|
||||||
|
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
>str = isD1(c2Ord1) && c2Ord1.p1 : string
|
||||||
|
>str : string
|
||||||
|
>isD1(c2Ord1) && c2Ord1.p1 : string
|
||||||
|
>isD1(c2Ord1) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1.p1 : string
|
||||||
|
>c2Ord1 : D1
|
||||||
|
>p1 : string
|
||||||
|
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
||||||
|
>r2 : C2 | D1
|
||||||
|
>C2 : C2
|
||||||
|
>D1 : D1
|
||||||
|
>isC1(c2Ord1) && c2Ord1 : D1
|
||||||
|
>isC1(c2Ord1) : boolean
|
||||||
|
>isC1 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1 : D1
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
//// [typeGuardOfFormIsTypeOnInterfaces.ts]
|
||||||
|
|
||||||
|
interface C1 {
|
||||||
|
(): C1;
|
||||||
|
prototype: C1;
|
||||||
|
p1: string;
|
||||||
|
}
|
||||||
|
interface C2 {
|
||||||
|
(): C2;
|
||||||
|
prototype: C2;
|
||||||
|
p2: number;
|
||||||
|
}
|
||||||
|
interface D1 extends C1 {
|
||||||
|
prototype: D1;
|
||||||
|
p3: number;
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
var num: number;
|
||||||
|
var strOrNum: string | number;
|
||||||
|
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1: C1;
|
||||||
|
var c2: C2;
|
||||||
|
var d1: D1;
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
||||||
|
|
||||||
|
//// [typeGuardOfFormIsTypeOnInterfaces.js]
|
||||||
|
var str;
|
||||||
|
var num;
|
||||||
|
var strOrNum;
|
||||||
|
function isC1(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function isC2(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function isD1(x) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var c1;
|
||||||
|
var c2;
|
||||||
|
var d1;
|
||||||
|
var c1Orc2;
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
var c2Ord1;
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
var r2 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
|
@ -0,0 +1,159 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts ===
|
||||||
|
|
||||||
|
interface C1 {
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0))
|
||||||
|
|
||||||
|
(): C1;
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0))
|
||||||
|
|
||||||
|
prototype: C1;
|
||||||
|
>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 2, 11))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0))
|
||||||
|
|
||||||
|
p1: string;
|
||||||
|
>p1 : Symbol(p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18))
|
||||||
|
}
|
||||||
|
interface C2 {
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
|
||||||
|
(): C2;
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
|
||||||
|
prototype: C2;
|
||||||
|
>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 7, 11))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
|
||||||
|
p2: number;
|
||||||
|
>p2 : Symbol(p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18))
|
||||||
|
}
|
||||||
|
interface D1 extends C1 {
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0))
|
||||||
|
|
||||||
|
prototype: D1;
|
||||||
|
>prototype : Symbol(prototype, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 11, 25))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1))
|
||||||
|
|
||||||
|
p3: number;
|
||||||
|
>p3 : Symbol(p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18))
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3))
|
||||||
|
|
||||||
|
var num: number;
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3))
|
||||||
|
|
||||||
|
var strOrNum: string | number;
|
||||||
|
>strOrNum : Symbol(strOrNum, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 3))
|
||||||
|
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30))
|
||||||
|
>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 20, 14))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1))
|
||||||
|
>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 24, 14))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1))
|
||||||
|
>x : Symbol(x, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 28, 14))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1))
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1: C1;
|
||||||
|
>c1 : Symbol(c1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 32, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0))
|
||||||
|
|
||||||
|
var c2: C2;
|
||||||
|
>c2 : Symbol(c2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 33, 3))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
|
||||||
|
var d1: D1;
|
||||||
|
>d1 : Symbol(d1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 34, 3))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1))
|
||||||
|
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>C1 : Symbol(C1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 0, 0))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3))
|
||||||
|
>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18))
|
||||||
|
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3))
|
||||||
|
>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>c1Orc2.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18))
|
||||||
|
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>c1Orc2.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18))
|
||||||
|
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>c1Orc2.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18))
|
||||||
|
>c1Orc2 : Symbol(c1Orc2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 35, 3))
|
||||||
|
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18))
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1))
|
||||||
|
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3))
|
||||||
|
>isC2 : Symbol(isC2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 22, 1))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>c2Ord1.p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>p2 : Symbol(C2.p2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 8, 18))
|
||||||
|
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
>num : Symbol(num, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 16, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>c2Ord1.p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>p3 : Symbol(D1.p3, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 12, 18))
|
||||||
|
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
>str : Symbol(str, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 15, 3))
|
||||||
|
>isD1 : Symbol(isD1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 26, 1))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>c2Ord1.p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>p1 : Symbol(C1.p1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 3, 18))
|
||||||
|
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
||||||
|
>r2 : Symbol(r2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 45, 3))
|
||||||
|
>C2 : Symbol(C2, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 5, 1))
|
||||||
|
>D1 : Symbol(D1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 10, 1))
|
||||||
|
>isC1 : Symbol(isC1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 17, 30))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
>c2Ord1 : Symbol(c2Ord1, Decl(typeGuardOfFormIsTypeOnInterfaces.ts, 41, 3))
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormIsTypeOnInterfaces.ts ===
|
||||||
|
|
||||||
|
interface C1 {
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
(): C1;
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
prototype: C1;
|
||||||
|
>prototype : C1
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
p1: string;
|
||||||
|
>p1 : string
|
||||||
|
}
|
||||||
|
interface C2 {
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
(): C2;
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
prototype: C2;
|
||||||
|
>prototype : C2
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
p2: number;
|
||||||
|
>p2 : number
|
||||||
|
}
|
||||||
|
interface D1 extends C1 {
|
||||||
|
>D1 : D1
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
prototype: D1;
|
||||||
|
>prototype : D1
|
||||||
|
>D1 : D1
|
||||||
|
|
||||||
|
p3: number;
|
||||||
|
>p3 : number
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
>str : string
|
||||||
|
|
||||||
|
var num: number;
|
||||||
|
>num : number
|
||||||
|
|
||||||
|
var strOrNum: string | number;
|
||||||
|
>strOrNum : string | number
|
||||||
|
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
>isC1 : (x: any) => boolean
|
||||||
|
>x : any
|
||||||
|
>x : any
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
>isC2 : (x: any) => boolean
|
||||||
|
>x : any
|
||||||
|
>x : any
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>x : any
|
||||||
|
>x : any
|
||||||
|
>D1 : D1
|
||||||
|
|
||||||
|
return true;
|
||||||
|
>true : boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1: C1;
|
||||||
|
>c1 : C1
|
||||||
|
>C1 : C1
|
||||||
|
|
||||||
|
var c2: C2;
|
||||||
|
>c2 : C2
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
var d1: D1;
|
||||||
|
>d1 : D1
|
||||||
|
>D1 : D1
|
||||||
|
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>C1 : C1
|
||||||
|
>C2 : C2
|
||||||
|
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
>str = isC1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>str : string
|
||||||
|
>isC1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>isC1(c1Orc2) : boolean
|
||||||
|
>isC1 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p1 : string
|
||||||
|
>c1Orc2 : C1
|
||||||
|
>p1 : string
|
||||||
|
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
>num = isC2(c1Orc2) && c1Orc2.p2 : number
|
||||||
|
>num : number
|
||||||
|
>isC2(c1Orc2) && c1Orc2.p2 : number
|
||||||
|
>isC2(c1Orc2) : boolean
|
||||||
|
>isC2 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p2 : number
|
||||||
|
>c1Orc2 : C2
|
||||||
|
>p2 : number
|
||||||
|
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
>str = isD1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>str : string
|
||||||
|
>isD1(c1Orc2) && c1Orc2.p1 : string
|
||||||
|
>isD1(c1Orc2) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p1 : string
|
||||||
|
>c1Orc2 : D1
|
||||||
|
>p1 : string
|
||||||
|
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
>num = isD1(c1Orc2) && c1Orc2.p3 : number
|
||||||
|
>num : number
|
||||||
|
>isD1(c1Orc2) && c1Orc2.p3 : number
|
||||||
|
>isD1(c1Orc2) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c1Orc2 : C1 | C2
|
||||||
|
>c1Orc2.p3 : number
|
||||||
|
>c1Orc2 : D1
|
||||||
|
>p3 : number
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>C2 : C2
|
||||||
|
>D1 : D1
|
||||||
|
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
>num = isC2(c2Ord1) && c2Ord1.p2 : number
|
||||||
|
>num : number
|
||||||
|
>isC2(c2Ord1) && c2Ord1.p2 : number
|
||||||
|
>isC2(c2Ord1) : boolean
|
||||||
|
>isC2 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1.p2 : number
|
||||||
|
>c2Ord1 : C2
|
||||||
|
>p2 : number
|
||||||
|
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
>num = isD1(c2Ord1) && c2Ord1.p3 : number
|
||||||
|
>num : number
|
||||||
|
>isD1(c2Ord1) && c2Ord1.p3 : number
|
||||||
|
>isD1(c2Ord1) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1.p3 : number
|
||||||
|
>c2Ord1 : D1
|
||||||
|
>p3 : number
|
||||||
|
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
>str = isD1(c2Ord1) && c2Ord1.p1 : string
|
||||||
|
>str : string
|
||||||
|
>isD1(c2Ord1) && c2Ord1.p1 : string
|
||||||
|
>isD1(c2Ord1) : boolean
|
||||||
|
>isD1 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1.p1 : string
|
||||||
|
>c2Ord1 : D1
|
||||||
|
>p1 : string
|
||||||
|
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
||||||
|
>r2 : C2 | D1
|
||||||
|
>C2 : C2
|
||||||
|
>D1 : D1
|
||||||
|
>isC1(c2Ord1) && c2Ord1 : D1
|
||||||
|
>isC1(c2Ord1) : boolean
|
||||||
|
>isC1 : (x: any) => boolean
|
||||||
|
>c2Ord1 : C2 | D1
|
||||||
|
>c2Ord1 : D1
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
|
||||||
|
class A {
|
||||||
|
propA: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
propB: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
propC: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isA(p1: any): p1 is A;
|
||||||
|
declare function isB(p1: any): p1 is B;
|
||||||
|
declare function isC(p1: any): p1 is C;
|
||||||
|
|
||||||
|
declare function retC(): C;
|
||||||
|
|
||||||
|
var a: A;
|
||||||
|
var b: B;
|
||||||
|
|
||||||
|
// Basic
|
||||||
|
if (isC(a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sub type
|
||||||
|
var subType: C;
|
||||||
|
if(isA(subType)) {
|
||||||
|
subType.propC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union type
|
||||||
|
var union: A | B;
|
||||||
|
if(isA(union)) {
|
||||||
|
union.propA;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call signature
|
||||||
|
interface I1 {
|
||||||
|
(p1: A): p1 is C;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The parameter index and argument index for the type guard target is matching.
|
||||||
|
// The type predicate type is assignable to the parameter type.
|
||||||
|
declare function isC_multipleParams(p1, p2): p1 is C;
|
||||||
|
if (isC_multipleParams(a, 0)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
var obj: {
|
||||||
|
func1(p1: A): p1 is C;
|
||||||
|
}
|
||||||
|
class D {
|
||||||
|
method1(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrow function
|
||||||
|
let f1 = (p1: A): p1 is C => false;
|
||||||
|
|
||||||
|
// Function type
|
||||||
|
declare function f2(p1: (p1: A) => p1 is C);
|
||||||
|
|
||||||
|
// Function expressions
|
||||||
|
f2(function(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Evaluations are asssignable to boolean.
|
||||||
|
declare function acceptingBoolean(a: boolean);
|
||||||
|
acceptingBoolean(isA(a));
|
||||||
|
|
||||||
|
// Type predicates with different parameter name.
|
||||||
|
declare function acceptingTypeGuardFunction(p1: (item) => item is A);
|
||||||
|
acceptingTypeGuardFunction(isA);
|
||||||
|
|
||||||
|
// Binary expressions
|
||||||
|
let union2: C | B;
|
||||||
|
let union3: boolean | B = isA(union2) || union2;
|
|
@ -0,0 +1,135 @@
|
||||||
|
|
||||||
|
class A {
|
||||||
|
propA: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
propB: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
propC: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasANonBooleanReturnStatement(x): x is A {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMissingIsKeyword(): x {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasMissingTypeInTypeGuardType(x): x is {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameter(y): x is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameterType1(x: A): x is B {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMatchingParameterType2(x: string): x is number {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasNonMathcingGenericType<T>(a: string): a is T[] {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let a: A;
|
||||||
|
let b: B;
|
||||||
|
|
||||||
|
declare function isB(p1): p1 is B;
|
||||||
|
declare function isC(p1): p1 is C;
|
||||||
|
declare function funA(p1: any, p2: any): p1 is B;
|
||||||
|
declare function hasNoTypeGuard(x);
|
||||||
|
|
||||||
|
// Passed argument is not the same as the one being guarded.
|
||||||
|
if (isB(b)) {
|
||||||
|
a.propB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter index and argument index for the type guard target is not matching.
|
||||||
|
if (funA(0, a)) {
|
||||||
|
a.propB; // Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// No type guard in if statement
|
||||||
|
if (hasNoTypeGuard(a)) {
|
||||||
|
a.propB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type predicate type is not assignable
|
||||||
|
declare function acceptingDifferentSignatureTypeGuardFunction(p1: (p1) => p1 is B);
|
||||||
|
acceptingDifferentSignatureTypeGuardFunction(isC);
|
||||||
|
|
||||||
|
// Boolean not assignable to type guard
|
||||||
|
var assign1: (p1, p2) => p1 is A;
|
||||||
|
assign1 = function(p1, p2): boolean {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must have matching parameter index
|
||||||
|
var assign2: (p1, p2) => p1 is A;
|
||||||
|
assign2 = function(p1, p2): p2 is A {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// No matching signature
|
||||||
|
var assign3: (p1, p2) => p1 is A;
|
||||||
|
assign3 = function(p1, p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Type predicates in non-return type positions
|
||||||
|
var b1: b is A;
|
||||||
|
function b2(a: b is A) {};
|
||||||
|
function b3(): A | b is A {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Non-compatiable type predicate positions for signature declarations
|
||||||
|
class D {
|
||||||
|
constructor(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
get m1(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
set m2(p1: A): p1 is C {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I1 {
|
||||||
|
new (p1: A): p1 is C;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I2 {
|
||||||
|
[index: number]: p1 is C;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference to rest parameter
|
||||||
|
function b4(...a): a is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reference to binding pattern
|
||||||
|
function b5({a, b, p1}, p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function b6([a, b, p1], p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function b7({a, b, c: {p1}}, p2, p3): p1 is A {
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
|
||||||
|
class A {
|
||||||
|
propA: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
propB: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
class C extends A {
|
||||||
|
propC: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare function isB(p1): p1 is B;
|
||||||
|
declare function isC(p1): p1 is C;
|
||||||
|
declare function retC(x): C;
|
||||||
|
|
||||||
|
declare function funA<T>(p1: (p1) => T): T;
|
||||||
|
declare function funB<T>(p1: (p1) => T, p2: any): p2 is T;
|
||||||
|
declare function funC<T>(p1: (p1) => p1 is T): T;
|
||||||
|
declare function funD<T>(p1: (p1) => p1 is T, p2: any): p2 is T;
|
||||||
|
declare function funE<T, U>(p1: (p1) => p1 is T, p2: U): T;
|
||||||
|
|
||||||
|
let a: A;
|
||||||
|
let test1: boolean = funA(isB);
|
||||||
|
if (funB(retC, a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
let test2: B = funC(isB);
|
||||||
|
if (funD(isC, a)) {
|
||||||
|
a.propC;
|
||||||
|
}
|
||||||
|
let test3: B = funE(isB, 1);
|
|
@ -0,0 +1,37 @@
|
||||||
|
|
||||||
|
class C1 {
|
||||||
|
p1: string;
|
||||||
|
}
|
||||||
|
class C2 {
|
||||||
|
p2: number;
|
||||||
|
}
|
||||||
|
class D1 extends C1 {
|
||||||
|
p3: number;
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
var num: number;
|
||||||
|
var strOrNum: string | number;
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
interface C1 {
|
||||||
|
(): C1;
|
||||||
|
prototype: C1;
|
||||||
|
p1: string;
|
||||||
|
}
|
||||||
|
interface C2 {
|
||||||
|
(): C2;
|
||||||
|
prototype: C2;
|
||||||
|
p2: number;
|
||||||
|
}
|
||||||
|
interface D1 extends C1 {
|
||||||
|
prototype: D1;
|
||||||
|
p3: number;
|
||||||
|
}
|
||||||
|
var str: string;
|
||||||
|
var num: number;
|
||||||
|
var strOrNum: string | number;
|
||||||
|
|
||||||
|
|
||||||
|
function isC1(x: any): x is C1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isC2(x: any): x is C2 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isD1(x: any): x is D1 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var c1: C1;
|
||||||
|
var c2: C2;
|
||||||
|
var d1: D1;
|
||||||
|
var c1Orc2: C1 | C2;
|
||||||
|
str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
||||||
|
num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
||||||
|
str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
||||||
|
num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
||||||
|
|
||||||
|
var c2Ord1: C2 | D1;
|
||||||
|
num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
||||||
|
num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
||||||
|
str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
||||||
|
var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
Loading…
Reference in a new issue