Merge pull request #3262 from tinganho/customTypeGuard2

Custom type guard function
This commit is contained in:
Jason Freeman 2015-06-08 20:26:32 -07:00
commit 6e69a9e380
27 changed files with 2842 additions and 41 deletions

0
bin/tsc Normal file → Executable file
View file

View file

@ -97,8 +97,8 @@ module ts {
let anyFunctionType = 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 unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false);
let anySignature = createSignature(undefined, undefined, emptyArray, anyType, undefined, 0, false, false);
let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, undefined, 0, false, false);
let globals: SymbolTable = {};
@ -1352,7 +1352,15 @@ module ts {
function symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string {
let writer = getSingleLineStringWriter();
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();
releaseStringWriter(writer);
@ -1362,7 +1370,6 @@ module ts {
function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string {
let writer = getSingleLineStringWriter();
getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
let result = writer.string();
releaseStringWriter(writer);
@ -1370,7 +1377,6 @@ module ts {
if (maxLength && result.length >= maxLength) {
result = result.substr(0, maxLength - "...".length) + "...";
}
return result;
}
@ -2782,7 +2788,7 @@ module ts {
function resolveDeclaredMembers(type: InterfaceType): InterfaceTypeWithDeclaredMembers {
if (!(<InterfaceTypeWithDeclaredMembers>type).declaredProperties) {
var symbol = type.symbol;
let symbol = type.symbol;
(<InterfaceTypeWithDeclaredMembers>type).declaredProperties = getNamedMembers(symbol.members);
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = getSignaturesOfSymbol(symbol.members["__call"]);
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = getSignaturesOfSymbol(symbol.members["__new"]);
@ -2833,12 +2839,13 @@ module ts {
}
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);
sig.declaration = declaration;
sig.typeParameters = typeParameters;
sig.parameters = parameters;
sig.resolvedReturnType = resolvedReturnType;
sig.typePredicate = typePredicate;
sig.minArgumentCount = minArgumentCount;
sig.hasRestParameter = hasRestParameter;
sig.hasStringLiterals = hasStringLiterals;
@ -2846,7 +2853,7 @@ module ts {
}
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);
}
@ -2863,7 +2870,7 @@ module ts {
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 {
@ -3239,11 +3246,20 @@ module ts {
}
let returnType: Type;
let typePredicate: TypePredicate;
if (classType) {
returnType = classType;
}
else if (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 {
// 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);
}
return links.resolvedSignature;
@ -3849,6 +3865,8 @@ module ts {
return getTypeFromStringLiteral(<StringLiteral>node);
case SyntaxKind.TypeReference:
return getTypeFromTypeReferenceOrExpressionWithTypeArguments(<TypeReferenceNode>node);
case SyntaxKind.TypePredicate:
return booleanType;
case SyntaxKind.ExpressionWithTypeArguments:
return getTypeFromTypeReferenceOrExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
case SyntaxKind.TypeQuery:
@ -3968,13 +3986,22 @@ module ts {
function instantiateSignature(signature: Signature, mapper: TypeMapper, eraseTypeParameters?: boolean): Signature {
let freshTypeParameters: TypeParameter[];
let freshTypePredicate: TypePredicate;
if (signature.typeParameters && !eraseTypeParameters) {
freshTypeParameters = instantiateList(signature.typeParameters, mapper, instantiateTypeParameter);
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,
instantiateList(signature.parameters, mapper, instantiateSymbol),
signature.resolvedReturnType ? instantiateType(signature.resolvedReturnType, mapper) : undefined,
freshTypePredicate,
signature.minArgumentCount, signature.hasRestParameter, signature.hasStringLiterals);
result.target = signature;
result.mapper = mapper;
@ -4631,6 +4658,44 @@ module ts {
}
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);
if (t === voidType) return result;
let s = getReturnTypeOfSignature(source);
@ -5163,6 +5228,16 @@ module ts {
function inferFromSignature(source: Signature, target: Signature) {
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));
}
@ -5547,7 +5622,7 @@ module ts {
let targetType: Type;
let prototypeProperty = getPropertyOfType(rightType, "prototype");
if (prototypeProperty) {
// Target type is type of the protoype property
// Target type is type of the prototype property
let prototypePropertyType = getTypeOfSymbol(prototypeProperty);
if (!isTypeAny(prototypePropertyType)) {
targetType = prototypePropertyType;
@ -5563,30 +5638,56 @@ module ts {
else if (rightType.flags & TypeFlags.Anonymous) {
constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
}
if (constructSignatures && constructSignatures.length) {
targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature))));
}
}
if (targetType) {
// Narrow to the target type if it's a subtype of the current type
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 getNarrowedType(type, targetType);
}
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
// will be a subtype or the same type as the argument.
function narrowType(type: Type, expr: Expression, assumeTrue: boolean): Type {
switch (expr.kind) {
case SyntaxKind.CallExpression:
return narrowTypeByTypePredicate(type, <CallExpression>expr, assumeTrue);
case SyntaxKind.ParenthesizedExpression:
return narrowType(type, (<ParenthesizedExpression>expr).expression, assumeTrue);
case SyntaxKind.BinaryExpression:
@ -8506,6 +8607,34 @@ module ts {
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) {
// Grammar checking
if (node.kind === SyntaxKind.IndexSignature) {
@ -8523,7 +8652,65 @@ module ts {
forEach(node.parameters, checkParameter);
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) {
@ -10085,9 +10272,10 @@ module ts {
if (node.expression) {
let func = getContainingFunction(node);
if (func) {
let returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
let signature = getSignatureFromDeclaration(func);
let returnType = getReturnTypeOfSignature(signature);
let exprType = checkExpressionCached(node.expression);
if (func.asteriskToken) {
// A generator does not need its return expressions checked against its return 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);
}
}
else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func)) {
else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func) || signature.typePredicate) {
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 {
if (!node) return;
switch (node.kind) {
@ -11184,6 +11378,8 @@ module ts {
return checkAccessorDeclaration(<AccessorDeclaration>node);
case SyntaxKind.TypeReference:
return checkTypeReferenceNode(<TypeReferenceNode>node);
case SyntaxKind.TypePredicate:
return checkTypePredicate(<TypePredicateNode>node);
case SyntaxKind.TypeQuery:
return checkTypeQuery(<TypeQueryNode>node);
case SyntaxKind.TypeLiteral:

View file

@ -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." },
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." },
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}'." },
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." },

View file

@ -703,6 +703,35 @@
"category": "Error",
"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}'.": {
"category": "Error",

View file

@ -103,6 +103,9 @@ module ts {
case SyntaxKind.TypeReference:
return visitNode(cbNode, (<TypeReferenceNode>node).typeName) ||
visitNodes(cbNodes, (<TypeReferenceNode>node).typeArguments);
case SyntaxKind.TypePredicate:
return visitNode(cbNode, (<TypePredicateNode>node).parameterName) ||
visitNode(cbNode, (<TypePredicateNode>node).type);
case SyntaxKind.TypeQuery:
return visitNode(cbNode, (<TypeQueryNode>node).exprName);
case SyntaxKind.TypeLiteral:
@ -1897,9 +1900,17 @@ module ts {
// TYPES
function parseTypeReference(): TypeReferenceNode {
let node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
node.typeName = parseEntityName(/*allowReservedWords*/ false, Diagnostics.Type_expected);
function parseTypeReferenceOrTypePredicate(): TypeReferenceNode | TypePredicateNode {
let 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) {
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
}
@ -2336,7 +2347,7 @@ module ts {
case SyntaxKind.SymbolKeyword:
// If these are followed by a dot, then parse these out as a dotted type reference instead.
let node = tryParse(parseKeywordAndNoDot);
return node || parseTypeReference();
return node || parseTypeReferenceOrTypePredicate();
case SyntaxKind.VoidKeyword:
return parseTokenNode<TypeNode>();
case SyntaxKind.TypeOfKeyword:
@ -2348,7 +2359,7 @@ module ts {
case SyntaxKind.OpenParenToken:
return parseParenthesizedType();
default:
return parseTypeReference();
return parseTypeReferenceOrTypePredicate();
}
}

View file

@ -72,6 +72,7 @@ module ts {
"in": SyntaxKind.InKeyword,
"instanceof": SyntaxKind.InstanceOfKeyword,
"interface": SyntaxKind.InterfaceKeyword,
"is": SyntaxKind.IsKeyword,
"let": SyntaxKind.LetKeyword,
"module": SyntaxKind.ModuleKeyword,
"namespace": SyntaxKind.NamespaceKeyword,

View file

@ -145,6 +145,7 @@ module ts {
ConstructorKeyword,
DeclareKeyword,
GetKeyword,
IsKeyword,
ModuleKeyword,
NamespaceKeyword,
RequireKeyword,
@ -177,6 +178,7 @@ module ts {
ConstructSignature,
IndexSignature,
// Type
TypePredicate,
TypeReference,
FunctionType,
ConstructorType,
@ -614,6 +616,11 @@ module ts {
typeArguments?: NodeArray<TypeNode>;
}
export interface TypePredicateNode extends TypeNode {
parameterName: Identifier;
type: TypeNode;
}
export interface TypeQueryNode extends TypeNode {
exprName: EntityName;
}
@ -1386,6 +1393,12 @@ module ts {
NotAccessible,
CannotBeNamed
}
export interface TypePredicate {
parameterName: string;
parameterIndex: number;
type: Type;
}
/* @internal */
export type AnyImportSyntax = ImportDeclaration | ImportEqualsDeclaration;
@ -1593,12 +1606,12 @@ module ts {
Union = 0x00004000, // Union
Anonymous = 0x00008000, // Anonymous
Instantiated = 0x00010000, // Instantiated anonymous type
/* @internal */
/* @internal */
FromSignature = 0x00020000, // Created for signature assignment check
ObjectLiteral = 0x00040000, // Originates in an object literal
/* @internal */
/* @internal */
ContainsUndefinedOrNull = 0x00080000, // Type is or contains Undefined or Null type
/* @internal */
/* @internal */
ContainsObjectLiteral = 0x00100000, // Type is or contains object literal type
ESSymbol = 0x00200000, // Type of symbol primitive introduced in ES6
@ -1714,6 +1727,7 @@ module ts {
declaration: SignatureDeclaration; // Originating declaration
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
parameters: Symbol[]; // Parameters
typePredicate?: TypePredicate; // Type predicate
/* @internal */
resolvedReturnType: Type; // Resolved return type
/* @internal */

View file

@ -75,26 +75,26 @@ function delint(sourceFile) {
delintNode(sourceFile);
function delintNode(node) {
switch (node.kind) {
case 187 /* ForStatement */:
case 188 /* ForInStatement */:
case 186 /* WhileStatement */:
case 185 /* DoStatement */:
if (node.statement.kind !== 180 /* Block */) {
case 189 /* ForStatement */:
case 190 /* ForInStatement */:
case 188 /* WhileStatement */:
case 187 /* DoStatement */:
if (node.statement.kind !== 182 /* Block */) {
report(node, "A looping statement's contents should be wrapped in a block body.");
}
break;
case 184 /* IfStatement */:
case 186 /* IfStatement */:
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.");
}
if (ifStatement.elseStatement &&
ifStatement.elseStatement.kind !== 180 /* Block */ &&
ifStatement.elseStatement.kind !== 184 /* IfStatement */) {
ifStatement.elseStatement.kind !== 182 /* Block */ &&
ifStatement.elseStatement.kind !== 186 /* IfStatement */) {
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
}
break;
case 170 /* BinaryExpression */:
case 172 /* BinaryExpression */:
var op = node.operatorToken.kind;
if (op === 28 /* EqualsEqualsToken */ || op == 29 /* ExclamationEqualsToken */) {
report(node, "Use '===' and '!=='.");

View 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;

View 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))

View 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

View 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;
}

View 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;
}

View 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);

View 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))

View 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

View 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

View 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))

View 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

View file

@ -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

View file

@ -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))

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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