Merge pull request #3262 from tinganho/customTypeGuard2
Custom type guard function
This commit is contained in:
commit
6e69a9e380
|
@ -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:
|
||||
|
|
|
@ -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." },
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 '!=='.");
|
||||
|
|
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