Merge pull request #3763 from tinganho/typePredicateDeclEmit
Fixes emit of type predicate in declaration files
This commit is contained in:
commit
e336701ba8
|
@ -25,12 +25,12 @@ namespace ts {
|
|||
// Cancellation that controls whether or not we can cancel in the middle of type checking.
|
||||
// In general cancelling is *not* safe for the type checker. We might be in the middle of
|
||||
// computing something, and we will leave our internals in an inconsistent state. Callers
|
||||
// who set the cancellation token should catch if a cancellation exception occurs, and
|
||||
// who set the cancellation token should catch if a cancellation exception occurs, and
|
||||
// should throw away and create a new TypeChecker.
|
||||
//
|
||||
// Currently we only support setting the cancellation token when getting diagnostics. This
|
||||
// is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
|
||||
// they no longer need the information (for example, if the user started editing again).
|
||||
// they no longer need the information (for example, if the user started editing again).
|
||||
let cancellationToken: CancellationToken;
|
||||
|
||||
let Symbol = objectAllocator.getSymbolConstructor();
|
||||
|
@ -117,7 +117,7 @@ namespace ts {
|
|||
let globals: SymbolTable = {};
|
||||
|
||||
let globalESSymbolConstructorSymbol: Symbol;
|
||||
|
||||
|
||||
let getGlobalPromiseConstructorSymbol: () => Symbol;
|
||||
|
||||
let globalObjectType: ObjectType;
|
||||
|
@ -148,7 +148,7 @@ namespace ts {
|
|||
let getInstantiatedGlobalPromiseLikeType: () => ObjectType;
|
||||
let getGlobalPromiseConstructorLikeType: () => ObjectType;
|
||||
let getGlobalThenableType: () => ObjectType;
|
||||
|
||||
|
||||
let tupleTypes: Map<TupleType> = {};
|
||||
let unionTypes: Map<UnionType> = {};
|
||||
let intersectionTypes: Map<IntersectionType> = {};
|
||||
|
@ -158,7 +158,7 @@ namespace ts {
|
|||
let emitParam = false;
|
||||
let emitAwaiter = false;
|
||||
let emitGenerator = false;
|
||||
|
||||
|
||||
let resolutionTargets: Object[] = [];
|
||||
let resolutionResults: boolean[] = [];
|
||||
|
||||
|
@ -406,7 +406,7 @@ namespace ts {
|
|||
let moduleExports = getSymbolOfNode(location).exports;
|
||||
if (location.kind === SyntaxKind.SourceFile ||
|
||||
(location.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>location).name.kind === SyntaxKind.StringLiteral)) {
|
||||
|
||||
|
||||
// It's an external module. Because of module/namespace merging, a module's exports are in scope,
|
||||
// yet we never want to treat an export specifier as putting a member in scope. Therefore,
|
||||
// if the name we find is purely an export specifier, it is not actually considered in scope.
|
||||
|
@ -526,7 +526,7 @@ namespace ts {
|
|||
}
|
||||
break;
|
||||
case SyntaxKind.Decorator:
|
||||
// Decorators are resolved at the class declaration. Resolving at the parameter
|
||||
// Decorators are resolved at the class declaration. Resolving at the parameter
|
||||
// or member would result in looking up locals in the method.
|
||||
//
|
||||
// function y() {}
|
||||
|
@ -1948,7 +1948,19 @@ namespace ts {
|
|||
writePunctuation(writer, SyntaxKind.ColonToken);
|
||||
}
|
||||
writeSpace(writer);
|
||||
buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags, symbolStack);
|
||||
|
||||
let returnType: Type;
|
||||
if (signature.typePredicate) {
|
||||
writer.writeParameter(signature.typePredicate.parameterName);
|
||||
writeSpace(writer);
|
||||
writeKeyword(writer, SyntaxKind.IsKeyword);
|
||||
writeSpace(writer);
|
||||
returnType = signature.typePredicate.type;
|
||||
}
|
||||
else {
|
||||
returnType = getReturnTypeOfSignature(signature);
|
||||
}
|
||||
buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack);
|
||||
}
|
||||
|
||||
function buildSignatureDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
|
||||
|
@ -2098,7 +2110,7 @@ namespace ts {
|
|||
case SyntaxKind.ParenthesizedType:
|
||||
return isDeclarationVisible(<Declaration>node.parent);
|
||||
|
||||
// Default binding, import specifier and namespace import is visible
|
||||
// Default binding, import specifier and namespace import is visible
|
||||
// only on demand so by default it is not visible
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
|
@ -3864,7 +3876,7 @@ namespace ts {
|
|||
function getGlobalType(name: string, arity = 0): ObjectType {
|
||||
return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), arity);
|
||||
}
|
||||
|
||||
|
||||
function tryGetGlobalType(name: string, arity = 0): ObjectType {
|
||||
return getTypeOfGlobalSymbol(getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined), arity);
|
||||
}
|
||||
|
@ -3892,7 +3904,7 @@ namespace ts {
|
|||
? createTypeReference(<GenericType>globalTypedPropertyDescriptorType, [propertyType])
|
||||
: emptyObjectType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a global type that is generic with some element type, and returns that instantiation.
|
||||
*/
|
||||
|
@ -4117,7 +4129,7 @@ namespace ts {
|
|||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
|
||||
function getTypeFromTypeNode(node: TypeNode): Type {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
|
@ -6053,7 +6065,7 @@ namespace ts {
|
|||
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (node.parserContextFlags & ParserContextFlags.Await) {
|
||||
getNodeLinks(container).flags |= NodeCheckFlags.CaptureArguments;
|
||||
getNodeLinks(node).flags |= NodeCheckFlags.LexicalArguments;
|
||||
|
@ -6746,7 +6758,7 @@ namespace ts {
|
|||
// c is represented in the tree as a spread element in an array literal.
|
||||
// But c really functions as a rest element, and its purpose is to provide
|
||||
// a contextual type for the right hand side of the assignment. Therefore,
|
||||
// instead of calling checkExpression on "...c", which will give an error
|
||||
// instead of calling checkExpression on "...c", which will give an error
|
||||
// if c is not iterable/array-like, we need to act as if we are trying to
|
||||
// get the contextual element type from it. So we do something similar to
|
||||
// getContextualTypeForElementExpression, which will crucially not error
|
||||
|
@ -7399,7 +7411,7 @@ namespace ts {
|
|||
|
||||
if (flags & NodeFlags.Abstract) {
|
||||
// A method cannot be accessed in a super property access if the method is abstract.
|
||||
// This error could mask a private property access error. But, a member
|
||||
// This error could mask a private property access error. But, a member
|
||||
// cannot simultaneously be private and abstract, so this will trigger an
|
||||
// additional error elsewhere.
|
||||
|
||||
|
@ -7478,7 +7490,7 @@ namespace ts {
|
|||
}
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
|
||||
getNodeLinks(node).resolvedSymbol = prop;
|
||||
|
||||
if (prop.parent && prop.parent.flags & SymbolFlags.Class) {
|
||||
|
@ -7875,7 +7887,7 @@ namespace ts {
|
|||
let paramType = getTypeAtPosition(signature, i);
|
||||
let argType = getEffectiveArgumentType(node, i, arg);
|
||||
|
||||
// If the effective argument type is 'undefined', there is no synthetic type
|
||||
// If the effective argument type is 'undefined', there is no synthetic type
|
||||
// for the argument. In that case, we should check the argument.
|
||||
if (argType === undefined) {
|
||||
// For context sensitive arguments we pass the identityMapper, which is a signal to treat all
|
||||
|
@ -7947,8 +7959,8 @@ namespace ts {
|
|||
// Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
|
||||
let paramType = getTypeAtPosition(signature, i);
|
||||
let argType = getEffectiveArgumentType(node, i, arg);
|
||||
|
||||
// If the effective argument type is 'undefined', there is no synthetic type
|
||||
|
||||
// If the effective argument type is 'undefined', there is no synthetic type
|
||||
// for the argument. In that case, we should check the argument.
|
||||
if (argType === undefined) {
|
||||
argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors
|
||||
|
@ -8001,18 +8013,18 @@ namespace ts {
|
|||
return args;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the effective argument count for a node that works like a function invocation.
|
||||
* If 'node' is a Decorator, the number of arguments is derived from the decoration
|
||||
* target and the signature:
|
||||
* If 'node.target' is a class declaration or class expression, the effective argument
|
||||
* If 'node.target' is a class declaration or class expression, the effective argument
|
||||
* count is 1.
|
||||
* If 'node.target' is a parameter declaration, the effective argument count is 3.
|
||||
* If 'node.target' is a property declaration, the effective argument count is 2.
|
||||
* If 'node.target' is a method or accessor declaration, the effective argument count
|
||||
* If 'node.target' is a method or accessor declaration, the effective argument count
|
||||
* is 3, although it can be 2 if the signature only accepts two arguments, allowing
|
||||
* us to match a property decorator.
|
||||
* us to match a property decorator.
|
||||
* Otherwise, the argument count is the length of the 'args' array.
|
||||
*/
|
||||
function getEffectiveArgumentCount(node: CallLikeExpression, args: Expression[], signature: Signature) {
|
||||
|
@ -8024,7 +8036,7 @@ namespace ts {
|
|||
return 1;
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
// A property declaration decorator will have two arguments (see
|
||||
// A property declaration decorator will have two arguments (see
|
||||
// `PropertyDecorator` in core.d.ts)
|
||||
return 2;
|
||||
|
||||
|
@ -8033,12 +8045,12 @@ namespace ts {
|
|||
case SyntaxKind.SetAccessor:
|
||||
// A method or accessor declaration decorator will have two or three arguments (see
|
||||
// `PropertyDecorator` and `MethodDecorator` in core.d.ts)
|
||||
// If the method decorator signature only accepts a target and a key, we will only
|
||||
// If the method decorator signature only accepts a target and a key, we will only
|
||||
// type check those arguments.
|
||||
return signature.parameters.length >= 3 ? 3 : 2;
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// A parameter declaration decorator will have three arguments (see
|
||||
// A parameter declaration decorator will have three arguments (see
|
||||
// `ParameterDecorator` in core.d.ts)
|
||||
|
||||
return 3;
|
||||
|
@ -8048,47 +8060,47 @@ namespace ts {
|
|||
return args.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the effective type of the first argument to a decorator.
|
||||
* If 'node' is a class declaration or class expression, the effective argument type
|
||||
* is the type of the static side of the class.
|
||||
* If 'node' is a parameter declaration, the effective argument type is either the type
|
||||
* of the static or instance side of the class for the parameter's parent method,
|
||||
* of the static or instance side of the class for the parameter's parent method,
|
||||
* depending on whether the method is declared static.
|
||||
* For a constructor, the type is always the type of the static side of the class.
|
||||
* If 'node' is a property, method, or accessor declaration, the effective argument
|
||||
* type is the type of the static or instance side of the parent class for class
|
||||
* element, depending on whether the element is declared static.
|
||||
* If 'node' is a property, method, or accessor declaration, the effective argument
|
||||
* type is the type of the static or instance side of the parent class for class
|
||||
* element, depending on whether the element is declared static.
|
||||
*/
|
||||
function getEffectiveDecoratorFirstArgumentType(node: Node): Type {
|
||||
// The first argument to a decorator is its `target`.
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
// For a class decorator, the `target` is the type of the class (e.g. the
|
||||
// For a class decorator, the `target` is the type of the class (e.g. the
|
||||
// "static" or "constructor" side of the class)
|
||||
let classSymbol = getSymbolOfNode(node);
|
||||
return getTypeOfSymbol(classSymbol);
|
||||
|
||||
case SyntaxKind.Parameter:
|
||||
// For a parameter decorator, the `target` is the parent type of the
|
||||
// parameter's containing method.
|
||||
// For a parameter decorator, the `target` is the parent type of the
|
||||
// parameter's containing method.
|
||||
node = node.parent;
|
||||
if (node.kind === SyntaxKind.Constructor) {
|
||||
let classSymbol = getSymbolOfNode(node);
|
||||
return getTypeOfSymbol(classSymbol);
|
||||
}
|
||||
|
||||
|
||||
// fall-through
|
||||
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
// For a property or method decorator, the `target` is the
|
||||
// "static"-side type of the parent of the member if the member is
|
||||
// declared "static"; otherwise, it is the "instance"-side type of the
|
||||
// declared "static"; otherwise, it is the "instance"-side type of the
|
||||
// parent of the member.
|
||||
return getParentTypeOfClassElement(<ClassElement>node);
|
||||
|
||||
|
@ -8097,19 +8109,19 @@ namespace ts {
|
|||
return unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the effective type for the second argument to a decorator.
|
||||
* If 'node' is a parameter, its effective argument type is one of the following:
|
||||
* If 'node.parent' is a constructor, the effective argument type is 'any', as we
|
||||
* If 'node.parent' is a constructor, the effective argument type is 'any', as we
|
||||
* will emit `undefined`.
|
||||
* If 'node.parent' is a member with an identifier, numeric, or string literal name,
|
||||
* If 'node.parent' is a member with an identifier, numeric, or string literal name,
|
||||
* the effective argument type will be a string literal type for the member name.
|
||||
* If 'node.parent' is a computed property name, the effective argument type will
|
||||
* If 'node.parent' is a computed property name, the effective argument type will
|
||||
* either be a symbol type or the string type.
|
||||
* If 'node' is a member with an identifier, numeric, or string literal name, the
|
||||
* If 'node' is a member with an identifier, numeric, or string literal name, the
|
||||
* effective argument type will be a string literal type for the member name.
|
||||
* If 'node' is a computed property name, the effective argument type will either
|
||||
* If 'node' is a computed property name, the effective argument type will either
|
||||
* be a symbol type or the string type.
|
||||
* A class decorator does not have a second argument type.
|
||||
*/
|
||||
|
@ -8126,18 +8138,18 @@ namespace ts {
|
|||
// For a constructor parameter decorator, the `propertyKey` will be `undefined`.
|
||||
return anyType;
|
||||
}
|
||||
|
||||
|
||||
// For a non-constructor parameter decorator, the `propertyKey` will be either
|
||||
// a string or a symbol, based on the name of the parameter's containing method.
|
||||
|
||||
|
||||
// fall-through
|
||||
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
// The `propertyKey` for a property or method decorator will be a
|
||||
// string literal type if the member name is an identifier, number, or string;
|
||||
// string literal type if the member name is an identifier, number, or string;
|
||||
// otherwise, if the member name is a computed property name it will
|
||||
// be either string or symbol.
|
||||
let element = <ClassElement>node;
|
||||
|
@ -8167,11 +8179,11 @@ namespace ts {
|
|||
return unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the effective argument type for the third argument to a decorator.
|
||||
* If 'node' is a parameter, the effective argument type is the number type.
|
||||
* If 'node' is a method or accessor, the effective argument type is a
|
||||
* If 'node' is a method or accessor, the effective argument type is a
|
||||
* `TypedPropertyDescriptor<T>` instantiated with the type of the member.
|
||||
* Class and property decorators do not have a third effective argument.
|
||||
*/
|
||||
|
@ -8204,7 +8216,7 @@ namespace ts {
|
|||
return unknownType;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the effective argument type for the provided argument to a decorator.
|
||||
*/
|
||||
|
@ -8222,12 +8234,12 @@ namespace ts {
|
|||
Debug.fail("Decorators should not have a fourth synthetic argument.");
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the effective argument type for an argument in a call expression.
|
||||
*/
|
||||
function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number, arg: Expression): Type {
|
||||
// Decorators provide special arguments, a tagged template expression provides
|
||||
// Decorators provide special arguments, a tagged template expression provides
|
||||
// a special first argument, and string literals get string literal types
|
||||
// unless we're reporting errors
|
||||
if (node.kind === SyntaxKind.Decorator) {
|
||||
|
@ -8238,12 +8250,12 @@ namespace ts {
|
|||
}
|
||||
|
||||
// This is not a synthetic argument, so we return 'undefined'
|
||||
// to signal that the caller needs to check the argument.
|
||||
// to signal that the caller needs to check the argument.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the effective argument expression for an argument in a call expression.
|
||||
* Gets the effective argument expression for an argument in a call expression.
|
||||
*/
|
||||
function getEffectiveArgument(node: CallLikeExpression, args: Expression[], argIndex: number) {
|
||||
// For a decorator or the first argument of a tagged template expression we return undefined.
|
||||
|
@ -8309,7 +8321,7 @@ namespace ts {
|
|||
// For a tagged template, then the first argument be 'undefined' if necessary
|
||||
// because it represents a TemplateStringsArray.
|
||||
//
|
||||
// For a decorator, no arguments are susceptible to contextual typing due to the fact
|
||||
// For a decorator, no arguments are susceptible to contextual typing due to the fact
|
||||
// decorators are applied to a declaration by the emitter, and not to an expression.
|
||||
let excludeArgument: boolean[];
|
||||
if (!isDecorator) {
|
||||
|
@ -8651,7 +8663,7 @@ namespace ts {
|
|||
|
||||
return resolveCall(node, callSignatures, candidatesOutArray);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression.
|
||||
*/
|
||||
|
@ -8797,7 +8809,7 @@ namespace ts {
|
|||
links.type = instantiateType(getTypeOfSymbol(lastOrUndefined(context.parameters)), mapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function createPromiseType(promisedType: Type): Type {
|
||||
// creates a `Promise<T>` type where `T` is the promisedType argument
|
||||
let globalPromiseType = getGlobalPromiseType();
|
||||
|
@ -8806,7 +8818,7 @@ namespace ts {
|
|||
promisedType = getAwaitedType(promisedType);
|
||||
return createTypeReference(<GenericType>globalPromiseType, [promisedType]);
|
||||
}
|
||||
|
||||
|
||||
return emptyObjectType;
|
||||
}
|
||||
|
||||
|
@ -8815,15 +8827,15 @@ namespace ts {
|
|||
if (!func.body) {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
|
||||
let isAsync = isAsyncFunctionLike(func);
|
||||
let type: Type;
|
||||
if (func.body.kind !== SyntaxKind.Block) {
|
||||
type = checkExpressionCached(<Expression>func.body, contextualMapper);
|
||||
type = checkExpressionCached(<Expression>func.body, contextualMapper);
|
||||
if (isAsync) {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// return type of the body should be unwrapped to its awaited type, which we will wrap in
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// return type of the body should be unwrapped to its awaited type, which we will wrap in
|
||||
// the native Promise<T> type later in this function.
|
||||
type = checkAwaitedType(type, func, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
|
||||
}
|
||||
|
@ -8852,13 +8864,13 @@ namespace ts {
|
|||
error(func, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
|
||||
return promiseType;
|
||||
}
|
||||
else {
|
||||
return voidType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// When yield/return statements are contextually typed we allow the return type to be a union type.
|
||||
// Otherwise we require the yield/return expressions to have a best common supertype.
|
||||
|
@ -8881,19 +8893,19 @@ namespace ts {
|
|||
if (!contextualSignature) {
|
||||
reportErrorsFromWidening(func, type);
|
||||
}
|
||||
|
||||
|
||||
let widenedType = getWidenedType(type);
|
||||
if (isAsync) {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// return type of the body is awaited type of the body, wrapped in a native Promise<T> type.
|
||||
let promiseType = createPromiseType(widenedType);
|
||||
if (promiseType === emptyObjectType) {
|
||||
error(func, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
return promiseType;
|
||||
|
||||
return promiseType;
|
||||
}
|
||||
else {
|
||||
return widenedType;
|
||||
|
@ -8928,13 +8940,13 @@ namespace ts {
|
|||
forEachReturnStatement(body, returnStatement => {
|
||||
let expr = returnStatement.expression;
|
||||
if (expr) {
|
||||
let type = checkExpressionCached(expr, contextualMapper);
|
||||
let type = checkExpressionCached(expr, contextualMapper);
|
||||
if (isAsync) {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// return type of the body should be unwrapped to its awaited type, which should be wrapped in
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// return type of the body should be unwrapped to its awaited type, which should be wrapped in
|
||||
// the native Promise<T> type by the caller.
|
||||
type = checkAwaitedType(type, body.parent, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
|
||||
type = checkAwaitedType(type, body.parent, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
|
||||
}
|
||||
|
||||
if (!contains(aggregatedTypes, type)) {
|
||||
|
@ -9006,12 +9018,12 @@ namespace ts {
|
|||
if (contextualMapper === identityMapper && isContextSensitive(node)) {
|
||||
return anyFunctionType;
|
||||
}
|
||||
|
||||
|
||||
let isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync) {
|
||||
emitAwaiter = true;
|
||||
}
|
||||
|
||||
|
||||
let links = getNodeLinks(node);
|
||||
let type = getTypeOfSymbol(node.symbol);
|
||||
// Check if function expression is contextually typed and assign parameter types if so
|
||||
|
@ -9048,7 +9060,7 @@ namespace ts {
|
|||
|
||||
function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
|
||||
|
||||
let isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync) {
|
||||
emitAwaiter = true;
|
||||
|
@ -9059,7 +9071,7 @@ namespace ts {
|
|||
if (returnType && isAsync) {
|
||||
promisedType = checkAsyncFunctionReturnType(node);
|
||||
}
|
||||
|
||||
|
||||
if (returnType && !node.asteriskToken) {
|
||||
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, isAsync ? promisedType : returnType);
|
||||
}
|
||||
|
@ -9078,10 +9090,10 @@ namespace ts {
|
|||
checkSourceElement(node.body);
|
||||
}
|
||||
else {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so we
|
||||
// should not be checking assignability of a promise to the return type. Instead, we need to
|
||||
// check assignability of the awaited type of the expression body against the promised type of
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so we
|
||||
// should not be checking assignability of a promise to the return type. Instead, we need to
|
||||
// check assignability of the awaited type of the expression body against the promised type of
|
||||
// its return type annotation.
|
||||
let exprType = checkExpression(<Expression>node.body);
|
||||
if (returnType) {
|
||||
|
@ -9093,7 +9105,7 @@ namespace ts {
|
|||
checkTypeAssignableTo(exprType, returnType, node.body);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
checkFunctionAndClassExpressionBodies(node.body);
|
||||
}
|
||||
}
|
||||
|
@ -9215,7 +9227,7 @@ namespace ts {
|
|||
let operandType = checkExpression(node.expression);
|
||||
return checkAwaitedType(operandType, node);
|
||||
}
|
||||
|
||||
|
||||
function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
|
||||
let operandType = checkExpression(node.operand);
|
||||
switch (node.operator) {
|
||||
|
@ -9688,7 +9700,7 @@ namespace ts {
|
|||
node.contextualType = saveContextualType;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function checkExpressionCached(node: Expression, contextualMapper?: TypeMapper): Type {
|
||||
let links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
|
@ -9895,7 +9907,7 @@ namespace ts {
|
|||
if (node.questionToken && isBindingPattern(node.name) && func.body) {
|
||||
error(node, Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature);
|
||||
}
|
||||
|
||||
|
||||
// Only check rest parameter type if it's not a binding pattern. Since binding patterns are
|
||||
// not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
|
||||
if (node.dotDotDotToken && !isBindingPattern(node.name) && !isArrayType(getTypeOfSymbol(node.symbol))) {
|
||||
|
@ -10113,7 +10125,7 @@ namespace ts {
|
|||
|
||||
// Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
|
||||
checkFunctionLikeDeclaration(node);
|
||||
|
||||
|
||||
// Abstract methods cannot have an implementation.
|
||||
// Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
|
||||
if(node.flags & NodeFlags.Abstract && node.body) {
|
||||
|
@ -10548,7 +10560,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
// Abstract methods can't have an implementation -- in particular, they don't need one.
|
||||
if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
|
||||
if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
|
||||
!(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract) ) {
|
||||
reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
|
||||
}
|
||||
|
@ -10666,13 +10678,13 @@ namespace ts {
|
|||
if (!message) {
|
||||
message = Diagnostics.Operand_for_await_does_not_have_a_valid_callable_then_member;
|
||||
}
|
||||
|
||||
|
||||
error(location, message);
|
||||
}
|
||||
|
||||
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -10690,16 +10702,16 @@ namespace ts {
|
|||
// ) => any
|
||||
// ): any;
|
||||
// }
|
||||
//
|
||||
|
||||
//
|
||||
|
||||
if (promise.flags & TypeFlags.Any) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
if ((promise.flags & TypeFlags.Reference) && (<GenericType>promise).target === tryGetGlobalPromiseType()) {
|
||||
return (<GenericType>promise).typeArguments[0];
|
||||
}
|
||||
|
||||
|
||||
let globalPromiseLikeType = getInstantiatedGlobalPromiseLikeType();
|
||||
if (globalPromiseLikeType === emptyObjectType || !isTypeAssignableTo(promise, globalPromiseLikeType)) {
|
||||
return undefined;
|
||||
|
@ -10709,58 +10721,58 @@ namespace ts {
|
|||
if (thenFunction && (thenFunction.flags & TypeFlags.Any)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
let thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, SignatureKind.Call) : emptyArray;
|
||||
if (thenSignatures.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
let onfulfilledParameterType = getUnionType(map(thenSignatures, getTypeOfFirstParameterOfSignature));
|
||||
if (onfulfilledParameterType.flags & TypeFlags.Any) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
let onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, SignatureKind.Call);
|
||||
if (onfulfilledParameterSignatures.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
let valueParameterType = getUnionType(map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature));
|
||||
return valueParameterType;
|
||||
}
|
||||
|
||||
|
||||
function getTypeOfFirstParameterOfSignature(signature: Signature) {
|
||||
return getTypeAtPosition(signature, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the "awaited type" of a type.
|
||||
* @param type The type to await.
|
||||
* @remarks The "awaited type" of an expression is its "promised type" if the expression is a
|
||||
* @remarks The "awaited type" of an expression is its "promised type" if the expression is a
|
||||
* Promise-like type; otherwise, it is the type of the expression. This is used to reflect
|
||||
* The runtime behavior of the `await` keyword.
|
||||
*/
|
||||
function getAwaitedType(type: Type) {
|
||||
return checkAwaitedType(type, /*location*/ undefined, /*message*/ undefined);
|
||||
}
|
||||
|
||||
|
||||
function checkAwaitedType(type: Type, location?: Node, message?: DiagnosticMessage) {
|
||||
return checkAwaitedTypeWorker(type);
|
||||
|
||||
|
||||
function checkAwaitedTypeWorker(type: Type): Type {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
let types: Type[] = [];
|
||||
for (let constituentType of (<UnionType>type).types) {
|
||||
types.push(checkAwaitedTypeWorker(constituentType));
|
||||
}
|
||||
|
||||
|
||||
return getUnionType(types);
|
||||
}
|
||||
else {
|
||||
let promisedType = getPromisedType(type);
|
||||
if (promisedType === undefined) {
|
||||
// The type was not a PromiseLike, so it could not be unwrapped any further.
|
||||
// As long as the type does not have a callable "then" property, it is
|
||||
// As long as the type does not have a callable "then" property, it is
|
||||
// safe to return the type; otherwise, an error will have been reported in
|
||||
// the call to checkNonThenableType and we will return unknownType.
|
||||
//
|
||||
|
@ -10771,7 +10783,7 @@ namespace ts {
|
|||
// The "thenable" does not match the minimal definition for a PromiseLike. When
|
||||
// a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
|
||||
// will never settle. We treat this as an error to help flag an early indicator
|
||||
// of a runtime problem. If the user wants to return this value from an async
|
||||
// of a runtime problem. If the user wants to return this value from an async
|
||||
// function, they would need to wrap it in some other value. If they want it to
|
||||
// be treated as a promise, they can cast to <any>.
|
||||
return checkNonThenableType(type, location, message);
|
||||
|
@ -10779,70 +10791,70 @@ namespace ts {
|
|||
else {
|
||||
if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) {
|
||||
// We have a bad actor in the form of a promise whose promised type is
|
||||
// the same promise type, or a mutually recursive promise. Return the
|
||||
// unknown type as we cannot guess the shape. If this were the actual
|
||||
// the same promise type, or a mutually recursive promise. Return the
|
||||
// unknown type as we cannot guess the shape. If this were the actual
|
||||
// case in the JavaScript, this Promise would never resolve.
|
||||
//
|
||||
// An example of a bad actor with a singly-recursive promise type might
|
||||
// An example of a bad actor with a singly-recursive promise type might
|
||||
// be:
|
||||
//
|
||||
// interface BadPromise {
|
||||
// then(
|
||||
// onfulfilled: (value: BadPromise) => any,
|
||||
// onfulfilled: (value: BadPromise) => any,
|
||||
// onrejected: (error: any) => any): BadPromise;
|
||||
// }
|
||||
//
|
||||
// The above interface will pass the PromiseLike check, and return a
|
||||
// promised type of `BadPromise`. Since this is a self reference, we
|
||||
// The above interface will pass the PromiseLike check, and return a
|
||||
// promised type of `BadPromise`. Since this is a self reference, we
|
||||
// don't want to keep recursing ad infinitum.
|
||||
//
|
||||
// An example of a bad actor in the form of a mutually-recursive
|
||||
// An example of a bad actor in the form of a mutually-recursive
|
||||
// promise type might be:
|
||||
//
|
||||
// interface BadPromiseA {
|
||||
// then(
|
||||
// onfulfilled: (value: BadPromiseB) => any,
|
||||
// onfulfilled: (value: BadPromiseB) => any,
|
||||
// onrejected: (error: any) => any): BadPromiseB;
|
||||
// }
|
||||
//
|
||||
// interface BadPromiseB {
|
||||
// then(
|
||||
// onfulfilled: (value: BadPromiseA) => any,
|
||||
// onfulfilled: (value: BadPromiseA) => any,
|
||||
// onrejected: (error: any) => any): BadPromiseA;
|
||||
// }
|
||||
//
|
||||
if (location) {
|
||||
error(
|
||||
location,
|
||||
Diagnostics._0_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method,
|
||||
location,
|
||||
Diagnostics._0_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method,
|
||||
symbolToString(type.symbol));
|
||||
}
|
||||
|
||||
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
|
||||
// Keep track of the type we're about to unwrap to avoid bad recursive promise types.
|
||||
// See the comments above for more information.
|
||||
awaitedTypeStack.push(type.id);
|
||||
let awaitedType = checkAwaitedTypeWorker(promisedType);
|
||||
awaitedTypeStack.pop();
|
||||
return awaitedType;
|
||||
return awaitedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the return type of an async function to ensure it is a compatible
|
||||
* Checks the return type of an async function to ensure it is a compatible
|
||||
* Promise implementation.
|
||||
* @param node The signature to check
|
||||
* @param returnType The return type for the function
|
||||
* @remarks
|
||||
* This checks that an async function has a valid Promise-compatible return type,
|
||||
* and returns the *awaited type* of the promise. An async function has a valid
|
||||
* Promise-compatible return type if the resolved value of the return type has a
|
||||
* @remarks
|
||||
* This checks that an async function has a valid Promise-compatible return type,
|
||||
* and returns the *awaited type* of the promise. An async function has a valid
|
||||
* Promise-compatible return type if the resolved value of the return type has a
|
||||
* construct signature that takes in an `initializer` function that in turn supplies
|
||||
* a `resolve` function as one of its arguments and results in an object with a
|
||||
* a `resolve` function as one of its arguments and results in an object with a
|
||||
* callable `then` signature.
|
||||
*/
|
||||
function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type {
|
||||
|
@ -10855,7 +10867,7 @@ namespace ts {
|
|||
|
||||
// As part of our emit for an async function, we will need to emit the entity name of
|
||||
// the return type annotation as an expression. To meet the necessary runtime semantics
|
||||
// for __awaiter, we must also check that the type of the declaration (e.g. the static
|
||||
// for __awaiter, we must also check that the type of the declaration (e.g. the static
|
||||
// side or "constructor" of the promise type) is compatible `PromiseConstructorLike`.
|
||||
//
|
||||
// An example might be (from lib.es6.d.ts):
|
||||
|
@ -10863,11 +10875,11 @@ namespace ts {
|
|||
// interface Promise<T> { ... }
|
||||
// interface PromiseConstructor {
|
||||
// new <T>(...): Promise<T>;
|
||||
// }
|
||||
// }
|
||||
// declare var Promise: PromiseConstructor;
|
||||
//
|
||||
// When an async function declares a return type annotation of `Promise<T>`, we
|
||||
// need to get the type of the `Promise` variable declaration above, which would
|
||||
// When an async function declares a return type annotation of `Promise<T>`, we
|
||||
// need to get the type of the `Promise` variable declaration above, which would
|
||||
// be `PromiseConstructor`.
|
||||
//
|
||||
// The same case applies to a class:
|
||||
|
@ -10879,20 +10891,20 @@ namespace ts {
|
|||
//
|
||||
// When we get the type of the `Promise` symbol here, we get the type of the static
|
||||
// side of the `Promise` class, which would be `{ new <T>(...): Promise<T> }`.
|
||||
|
||||
|
||||
let promiseType = getTypeFromTypeNode(node.type);
|
||||
if (promiseType === unknownType && compilerOptions.isolatedModules) {
|
||||
// If we are compiling with isolatedModules, we may not be able to resolve the
|
||||
// If we are compiling with isolatedModules, we may not be able to resolve the
|
||||
// type as a value. As such, we will just return unknownType;
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
|
||||
let promiseConstructor = getMergedSymbol(promiseType.symbol);
|
||||
if (!promiseConstructor || !symbolIsValue(promiseConstructor)) {
|
||||
error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeToString(promiseType));
|
||||
return unknownType
|
||||
}
|
||||
|
||||
|
||||
// Validate the promise constructor type.
|
||||
let promiseConstructorType = getTypeOfSymbol(promiseConstructor);
|
||||
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
|
||||
|
@ -10913,7 +10925,7 @@ namespace ts {
|
|||
// Get and return the awaited type of the return type.
|
||||
return checkAwaitedType(promiseType, node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
|
||||
}
|
||||
|
||||
|
||||
/** Check a decorator */
|
||||
function checkDecorator(node: Decorator): void {
|
||||
let signature = getResolvedSignature(node);
|
||||
|
@ -10963,11 +10975,11 @@ namespace ts {
|
|||
headMessage,
|
||||
errorInfo);
|
||||
}
|
||||
|
||||
|
||||
/** Checks a type reference node as an expression. */
|
||||
function checkTypeNodeAsExpression(node: TypeNode) {
|
||||
// When we are emitting type metadata for decorators, we need to try to check the type
|
||||
// as if it were an expression so that we can emit the type in a value position when we
|
||||
// as if it were an expression so that we can emit the type in a value position when we
|
||||
// serialize the type metadata.
|
||||
if (node && node.kind === SyntaxKind.TypeReference) {
|
||||
let type = getTypeFromTypeNode(node);
|
||||
|
@ -10982,7 +10994,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks the type annotation of an accessor declaration or property declaration as
|
||||
* Checks the type annotation of an accessor declaration or property declaration as
|
||||
* an expression if it is a type reference to a type with a value declaration.
|
||||
*/
|
||||
function checkTypeAnnotationAsExpression(node: AccessorDeclaration | PropertyDeclaration | ParameterDeclaration | MethodDeclaration) {
|
||||
|
@ -11004,7 +11016,7 @@ namespace ts {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Checks the type annotation of the parameters of a function/method or the constructor of a class as expressions */
|
||||
function checkParameterTypeAnnotationsAsExpressions(node: FunctionLikeDeclaration) {
|
||||
// ensure all type annotations with a value declaration are checked as an expression
|
||||
|
@ -11078,9 +11090,9 @@ namespace ts {
|
|||
if (!compilerOptions.experimentalAsyncFunctions) {
|
||||
error(node, Diagnostics.Experimental_support_for_async_functions_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalAsyncFunctions_to_remove_this_warning);
|
||||
}
|
||||
|
||||
|
||||
emitAwaiter = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not use hasDynamicName here, because that returns false for well known symbols.
|
||||
// We want to perform checkComputedPropertyName for all computed properties, including
|
||||
|
@ -11120,7 +11132,7 @@ namespace ts {
|
|||
if (isAsync) {
|
||||
promisedType = checkAsyncFunctionReturnType(node);
|
||||
}
|
||||
|
||||
|
||||
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, isAsync ? promisedType : returnType);
|
||||
}
|
||||
|
||||
|
@ -11332,7 +11344,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check that a parameter initializer contains no references to parameters declared to the right of itself
|
||||
function checkParameterInitializer(node: VariableLikeDeclaration): void {
|
||||
if (getRootDeclaration(node).kind !== SyntaxKind.Parameter) {
|
||||
|
@ -11653,7 +11665,7 @@ namespace ts {
|
|||
|
||||
return elementType || anyType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We want to treat type as an iterable, and get the type it is an iterable of. The iterable
|
||||
* must have the following structure (annotated with the names of the variables below):
|
||||
|
@ -12280,20 +12292,20 @@ namespace ts {
|
|||
// In order to resolve whether the inherited method was overriden in the base class or not,
|
||||
// we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
|
||||
// type declaration, derived and base resolve to the same symbol even in the case of generic classes.
|
||||
if (derived === base) {
|
||||
if (derived === base) {
|
||||
// derived class inherits base without override/redeclaration
|
||||
|
||||
let derivedClassDecl = getDeclarationOfKind(type.symbol, SyntaxKind.ClassDeclaration);
|
||||
|
||||
// It is an error to inherit an abstract member without implementing it or being declared abstract.
|
||||
// If there is no declaration for the derived class (as in the case of class expressions),
|
||||
// then the class cannot be declared abstract.
|
||||
// If there is no declaration for the derived class (as in the case of class expressions),
|
||||
// then the class cannot be declared abstract.
|
||||
if ( baseDeclarationFlags & NodeFlags.Abstract && (!derivedClassDecl || !(derivedClassDecl.flags & NodeFlags.Abstract))) {
|
||||
error(derivedClassDecl, Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2,
|
||||
typeToString(type), symbolToString(baseProperty), typeToString(baseType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
else {
|
||||
// derived overrides base.
|
||||
let derivedDeclarationFlags = getDeclarationFlagsFromSymbol(derived);
|
||||
if ((baseDeclarationFlags & NodeFlags.Private) || (derivedDeclarationFlags & NodeFlags.Private)) {
|
||||
|
@ -12764,7 +12776,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
// if the module merges with a class declaration in the same lexical scope,
|
||||
// if the module merges with a class declaration in the same lexical scope,
|
||||
// we need to track this to ensure the correct emit.
|
||||
let mergedClass = getDeclarationOfKind(symbol, SyntaxKind.ClassDeclaration);
|
||||
if (mergedClass &&
|
||||
|
@ -13298,7 +13310,7 @@ namespace ts {
|
|||
forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
|
||||
potentialThisCollisions.length = 0;
|
||||
}
|
||||
|
||||
|
||||
if (emitExtends) {
|
||||
links.flags |= NodeCheckFlags.EmitExtends;
|
||||
}
|
||||
|
@ -13310,11 +13322,11 @@ namespace ts {
|
|||
if (emitParam) {
|
||||
links.flags |= NodeCheckFlags.EmitParam;
|
||||
}
|
||||
|
||||
|
||||
if (emitAwaiter) {
|
||||
links.flags |= NodeCheckFlags.EmitAwaiter;
|
||||
}
|
||||
|
||||
|
||||
if (emitGenerator || (emitAwaiter && languageVersion < ScriptTarget.ES6)) {
|
||||
links.flags |= NodeCheckFlags.EmitGenerator;
|
||||
}
|
||||
|
@ -13713,7 +13725,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets either the static or instance type of a class element, based on
|
||||
* Gets either the static or instance type of a class element, based on
|
||||
* whether the element is declared as "static".
|
||||
*/
|
||||
function getParentTypeOfClassElement(node: ClassElement) {
|
||||
|
@ -13722,7 +13734,7 @@ namespace ts {
|
|||
? getTypeOfSymbol(classSymbol)
|
||||
: getDeclaredTypeOfSymbol(classSymbol);
|
||||
}
|
||||
|
||||
|
||||
// Return the list of properties of the given type, augmented with properties from Function
|
||||
// if the type has call or construct signatures
|
||||
function getAugmentedPropertiesOfType(type: Type): Symbol[] {
|
||||
|
@ -14061,7 +14073,7 @@ namespace ts {
|
|||
// * The serialized type of an AccessorDeclaration is the serialized type of the return type annotation of its getter or parameter type annotation of its setter.
|
||||
// * The serialized type of any other FunctionLikeDeclaration is "Function".
|
||||
// * The serialized type of any other node is "void 0".
|
||||
//
|
||||
//
|
||||
// For rules on serializing type annotations, see `serializeTypeNode`.
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ClassDeclaration: return "Function";
|
||||
|
@ -14075,14 +14087,14 @@ namespace ts {
|
|||
}
|
||||
return "void 0";
|
||||
}
|
||||
|
||||
|
||||
/** Serializes the parameter types of a function or the constructor of a class. Used by the __metadata decorator for a method or set accessor. */
|
||||
function serializeParameterTypesOfNode(node: Node): (string | string[])[] {
|
||||
// serialization of parameter types uses the following rules:
|
||||
//
|
||||
// * If the declaration is a class, the parameters of the first constructor with a body are used.
|
||||
// * If the declaration is function-like and has a body, the parameters of the function are used.
|
||||
//
|
||||
//
|
||||
// For the rules on serializing the type of each parameter declaration, see `serializeTypeOfDeclaration`.
|
||||
if (node) {
|
||||
var valueDeclaration: FunctionLikeDeclaration;
|
||||
|
@ -14299,21 +14311,21 @@ namespace ts {
|
|||
|
||||
anyArrayType = createArrayType(anyType);
|
||||
}
|
||||
|
||||
|
||||
function createInstantiatedPromiseLikeType(): ObjectType {
|
||||
let promiseLikeType = getGlobalPromiseLikeType();
|
||||
if (promiseLikeType !== emptyObjectType) {
|
||||
return createTypeReference(<GenericType>promiseLikeType, [anyType]);
|
||||
}
|
||||
|
||||
|
||||
return emptyObjectType;
|
||||
}
|
||||
|
||||
|
||||
function createThenableType() {
|
||||
// build the thenable type that is used to verify against a non-promise "thenable" operand to `await`.
|
||||
let thenPropertySymbol = createSymbol(SymbolFlags.Transient | SymbolFlags.Property, "then");
|
||||
getSymbolLinks(thenPropertySymbol).type = globalFunctionType;
|
||||
|
||||
|
||||
let thenableType = <ResolvedType>createObjectType(TypeFlags.Anonymous);
|
||||
thenableType.properties = [thenPropertySymbol];
|
||||
thenableType.members = createSymbolTable(thenableType.properties);
|
||||
|
|
|
@ -188,7 +188,7 @@ namespace ts {
|
|||
if (!moduleElementEmitInfo && asynchronousSubModuleDeclarationEmitInfo) {
|
||||
moduleElementEmitInfo = forEach(asynchronousSubModuleDeclarationEmitInfo, declEmitInfo => declEmitInfo.node === nodeToCheck ? declEmitInfo : undefined);
|
||||
}
|
||||
|
||||
|
||||
// If the alias was marked as not visible when we saw its declaration, we would have saved the aliasEmitInfo, but if we haven't yet visited the alias declaration
|
||||
// then we don't need to write it at this point. We will write it when we actually see its declaration
|
||||
// Eg.
|
||||
|
@ -198,7 +198,7 @@ namespace ts {
|
|||
// we would write alias foo declaration when we visit it since it would now be marked as visible
|
||||
if (moduleElementEmitInfo) {
|
||||
if (moduleElementEmitInfo.node.kind === SyntaxKind.ImportDeclaration) {
|
||||
// we have to create asynchronous output only after we have collected complete information
|
||||
// we have to create asynchronous output only after we have collected complete information
|
||||
// because it is possible to enable multiple bindings as asynchronously visible
|
||||
moduleElementEmitInfo.isVisible = true;
|
||||
}
|
||||
|
@ -353,6 +353,21 @@ namespace ts {
|
|||
return emitEntityName(<Identifier>type);
|
||||
case SyntaxKind.QualifiedName:
|
||||
return emitEntityName(<QualifiedName>type);
|
||||
case SyntaxKind.TypePredicate:
|
||||
return emitTypePredicate(<TypePredicateNode>type);
|
||||
}
|
||||
|
||||
function writeEntityName(entityName: EntityName | Expression) {
|
||||
if (entityName.kind === SyntaxKind.Identifier) {
|
||||
writeTextOfNode(currentSourceFile, entityName);
|
||||
}
|
||||
else {
|
||||
let left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
|
||||
let right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
|
||||
writeEntityName(left);
|
||||
write(".");
|
||||
writeTextOfNode(currentSourceFile, right);
|
||||
}
|
||||
}
|
||||
|
||||
function emitEntityName(entityName: EntityName | PropertyAccessExpression) {
|
||||
|
@ -362,19 +377,6 @@ namespace ts {
|
|||
|
||||
handleSymbolAccessibilityError(visibilityResult);
|
||||
writeEntityName(entityName);
|
||||
|
||||
function writeEntityName(entityName: EntityName | Expression) {
|
||||
if (entityName.kind === SyntaxKind.Identifier) {
|
||||
writeTextOfNode(currentSourceFile, entityName);
|
||||
}
|
||||
else {
|
||||
let left = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).left : (<PropertyAccessExpression>entityName).expression;
|
||||
let right = entityName.kind === SyntaxKind.QualifiedName ? (<QualifiedName>entityName).right : (<PropertyAccessExpression>entityName).name;
|
||||
writeEntityName(left);
|
||||
write(".");
|
||||
writeTextOfNode(currentSourceFile, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitExpressionWithTypeArguments(node: ExpressionWithTypeArguments) {
|
||||
|
@ -398,6 +400,12 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
function emitTypePredicate(type: TypePredicateNode) {
|
||||
writeTextOfNode(currentSourceFile, type.parameterName);
|
||||
write(" is ");
|
||||
emitType(type.type);
|
||||
}
|
||||
|
||||
function emitTypeQuery(type: TypeQueryNode) {
|
||||
write("typeof ");
|
||||
emitEntityName(type.exprName);
|
||||
|
@ -600,7 +608,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
function writeImportEqualsDeclaration(node: ImportEqualsDeclaration) {
|
||||
// note usage of writer. methods instead of aliases created, just to make sure we are using
|
||||
// note usage of writer. methods instead of aliases created, just to make sure we are using
|
||||
// correct writer especially to handle asynchronous alias writing
|
||||
emitJsDocComments(node);
|
||||
if (node.flags & NodeFlags.Export) {
|
||||
|
@ -642,7 +650,7 @@ namespace ts {
|
|||
|
||||
function writeImportDeclaration(node: ImportDeclaration) {
|
||||
if (!node.importClause && !(node.flags & NodeFlags.Export)) {
|
||||
// do not write non-exported import declarations that don't have import clauses
|
||||
// do not write non-exported import declarations that don't have import clauses
|
||||
return;
|
||||
}
|
||||
emitJsDocComments(node);
|
||||
|
@ -1517,7 +1525,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitNode(node: Node) {
|
||||
|
@ -1577,7 +1585,7 @@ namespace ts {
|
|||
referencePathsOutput += "/// <reference path=\"" + declFileName + "\" />" + newLine;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* @internal */
|
||||
export function writeDeclarationFile(jsFilePath: string, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, diagnostics: Diagnostic[]) {
|
||||
let emitDeclarationResult = emitDeclarations(host, resolver, diagnostics, jsFilePath, sourceFile);
|
||||
|
|
|
@ -26,6 +26,19 @@ export function fooWithSingleOverload(a: any) {
|
|||
return a;
|
||||
}
|
||||
|
||||
export function fooWithTypePredicate(a: any): a is number {
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypePredicateAndMulitpleParams(a: any, b: any, c: any): a is number {
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndGeneric<T>(a: any): a is T {
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndRestParam(a: any, ...rest): a is number {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** This comment should appear for nonExportedFoo*/
|
||||
function nonExportedFoo() {
|
||||
}
|
||||
|
@ -92,6 +105,26 @@ function fooWithSingleOverload(a) {
|
|||
return a;
|
||||
}
|
||||
exports.fooWithSingleOverload = fooWithSingleOverload;
|
||||
function fooWithTypePredicate(a) {
|
||||
return true;
|
||||
}
|
||||
exports.fooWithTypePredicate = fooWithTypePredicate;
|
||||
function fooWithTypePredicateAndMulitpleParams(a, b, c) {
|
||||
return true;
|
||||
}
|
||||
exports.fooWithTypePredicateAndMulitpleParams = fooWithTypePredicateAndMulitpleParams;
|
||||
function fooWithTypeTypePredicateAndGeneric(a) {
|
||||
return true;
|
||||
}
|
||||
exports.fooWithTypeTypePredicateAndGeneric = fooWithTypeTypePredicateAndGeneric;
|
||||
function fooWithTypeTypePredicateAndRestParam(a) {
|
||||
var rest = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
rest[_i - 1] = arguments[_i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
exports.fooWithTypeTypePredicateAndRestParam = fooWithTypeTypePredicateAndRestParam;
|
||||
/** This comment should appear for nonExportedFoo*/
|
||||
function nonExportedFoo() {
|
||||
}
|
||||
|
@ -144,6 +177,10 @@ export declare function fooWithRestParameters(a: string, ...rests: string[]): st
|
|||
export declare function fooWithOverloads(a: string): string;
|
||||
export declare function fooWithOverloads(a: number): number;
|
||||
export declare function fooWithSingleOverload(a: string): string;
|
||||
export declare function fooWithTypePredicate(a: any): a is number;
|
||||
export declare function fooWithTypePredicateAndMulitpleParams(a: any, b: any, c: any): a is number;
|
||||
export declare function fooWithTypeTypePredicateAndGeneric<T>(a: any): a is T;
|
||||
export declare function fooWithTypeTypePredicateAndRestParam(a: any, ...rest: any[]): a is number;
|
||||
//// [declFileFunctions_1.d.ts]
|
||||
/** This comment should appear for foo*/
|
||||
declare function globalfoo(): void;
|
||||
|
|
|
@ -57,49 +57,83 @@ export function fooWithSingleOverload(a: any) {
|
|||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 21, 38))
|
||||
}
|
||||
|
||||
export function fooWithTypePredicate(a: any): a is number {
|
||||
>fooWithTypePredicate : Symbol(fooWithTypePredicate, Decl(declFileFunctions_0.ts, 23, 1))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 25, 37))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 25, 37))
|
||||
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypePredicateAndMulitpleParams(a: any, b: any, c: any): a is number {
|
||||
>fooWithTypePredicateAndMulitpleParams : Symbol(fooWithTypePredicateAndMulitpleParams, Decl(declFileFunctions_0.ts, 27, 1))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 28, 54))
|
||||
>b : Symbol(b, Decl(declFileFunctions_0.ts, 28, 61))
|
||||
>c : Symbol(c, Decl(declFileFunctions_0.ts, 28, 69))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 28, 54))
|
||||
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndGeneric<T>(a: any): a is T {
|
||||
>fooWithTypeTypePredicateAndGeneric : Symbol(fooWithTypeTypePredicateAndGeneric, Decl(declFileFunctions_0.ts, 30, 1))
|
||||
>T : Symbol(T, Decl(declFileFunctions_0.ts, 31, 51))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 31, 54))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 31, 54))
|
||||
>T : Symbol(T, Decl(declFileFunctions_0.ts, 31, 51))
|
||||
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndRestParam(a: any, ...rest): a is number {
|
||||
>fooWithTypeTypePredicateAndRestParam : Symbol(fooWithTypeTypePredicateAndRestParam, Decl(declFileFunctions_0.ts, 33, 1))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 34, 53))
|
||||
>rest : Symbol(rest, Decl(declFileFunctions_0.ts, 34, 60))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 34, 53))
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** This comment should appear for nonExportedFoo*/
|
||||
function nonExportedFoo() {
|
||||
>nonExportedFoo : Symbol(nonExportedFoo, Decl(declFileFunctions_0.ts, 23, 1))
|
||||
>nonExportedFoo : Symbol(nonExportedFoo, Decl(declFileFunctions_0.ts, 36, 1))
|
||||
}
|
||||
/** This is comment for function signature*/
|
||||
function nonExportedFooWithParameters(/** this is comment about a*/a: string,
|
||||
>nonExportedFooWithParameters : Symbol(nonExportedFooWithParameters, Decl(declFileFunctions_0.ts, 27, 1))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 29, 38))
|
||||
>nonExportedFooWithParameters : Symbol(nonExportedFooWithParameters, Decl(declFileFunctions_0.ts, 40, 1))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 42, 38))
|
||||
|
||||
/** this is comment for b*/
|
||||
b: number) {
|
||||
>b : Symbol(b, Decl(declFileFunctions_0.ts, 29, 77))
|
||||
>b : Symbol(b, Decl(declFileFunctions_0.ts, 42, 77))
|
||||
|
||||
var d = a;
|
||||
>d : Symbol(d, Decl(declFileFunctions_0.ts, 32, 7))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 29, 38))
|
||||
>d : Symbol(d, Decl(declFileFunctions_0.ts, 45, 7))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 42, 38))
|
||||
}
|
||||
function nonExportedFooWithRestParameters(a: string, ...rests: string[]) {
|
||||
>nonExportedFooWithRestParameters : Symbol(nonExportedFooWithRestParameters, Decl(declFileFunctions_0.ts, 33, 1))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 34, 42))
|
||||
>rests : Symbol(rests, Decl(declFileFunctions_0.ts, 34, 52))
|
||||
>nonExportedFooWithRestParameters : Symbol(nonExportedFooWithRestParameters, Decl(declFileFunctions_0.ts, 46, 1))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 47, 42))
|
||||
>rests : Symbol(rests, Decl(declFileFunctions_0.ts, 47, 52))
|
||||
|
||||
return a + rests.join("");
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 34, 42))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 47, 42))
|
||||
>rests.join : Symbol(Array.join, Decl(lib.d.ts, 1035, 31))
|
||||
>rests : Symbol(rests, Decl(declFileFunctions_0.ts, 34, 52))
|
||||
>rests : Symbol(rests, Decl(declFileFunctions_0.ts, 47, 52))
|
||||
>join : Symbol(Array.join, Decl(lib.d.ts, 1035, 31))
|
||||
}
|
||||
|
||||
function nonExportedFooWithOverloads(a: string): string;
|
||||
>nonExportedFooWithOverloads : Symbol(nonExportedFooWithOverloads, Decl(declFileFunctions_0.ts, 36, 1), Decl(declFileFunctions_0.ts, 38, 56), Decl(declFileFunctions_0.ts, 39, 56))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 38, 37))
|
||||
>nonExportedFooWithOverloads : Symbol(nonExportedFooWithOverloads, Decl(declFileFunctions_0.ts, 49, 1), Decl(declFileFunctions_0.ts, 51, 56), Decl(declFileFunctions_0.ts, 52, 56))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 51, 37))
|
||||
|
||||
function nonExportedFooWithOverloads(a: number): number;
|
||||
>nonExportedFooWithOverloads : Symbol(nonExportedFooWithOverloads, Decl(declFileFunctions_0.ts, 36, 1), Decl(declFileFunctions_0.ts, 38, 56), Decl(declFileFunctions_0.ts, 39, 56))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 39, 37))
|
||||
>nonExportedFooWithOverloads : Symbol(nonExportedFooWithOverloads, Decl(declFileFunctions_0.ts, 49, 1), Decl(declFileFunctions_0.ts, 51, 56), Decl(declFileFunctions_0.ts, 52, 56))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 52, 37))
|
||||
|
||||
function nonExportedFooWithOverloads(a: any): any {
|
||||
>nonExportedFooWithOverloads : Symbol(nonExportedFooWithOverloads, Decl(declFileFunctions_0.ts, 36, 1), Decl(declFileFunctions_0.ts, 38, 56), Decl(declFileFunctions_0.ts, 39, 56))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 40, 37))
|
||||
>nonExportedFooWithOverloads : Symbol(nonExportedFooWithOverloads, Decl(declFileFunctions_0.ts, 49, 1), Decl(declFileFunctions_0.ts, 51, 56), Decl(declFileFunctions_0.ts, 52, 56))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 53, 37))
|
||||
|
||||
return a;
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 40, 37))
|
||||
>a : Symbol(a, Decl(declFileFunctions_0.ts, 53, 37))
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/declFileFunctions_1.ts ===
|
||||
|
|
|
@ -60,6 +60,44 @@ export function fooWithSingleOverload(a: any) {
|
|||
>a : any
|
||||
}
|
||||
|
||||
export function fooWithTypePredicate(a: any): a is number {
|
||||
>fooWithTypePredicate : (a: any) => a is number
|
||||
>a : any
|
||||
>a : any
|
||||
|
||||
return true;
|
||||
>true : boolean
|
||||
}
|
||||
export function fooWithTypePredicateAndMulitpleParams(a: any, b: any, c: any): a is number {
|
||||
>fooWithTypePredicateAndMulitpleParams : (a: any, b: any, c: any) => a is number
|
||||
>a : any
|
||||
>b : any
|
||||
>c : any
|
||||
>a : any
|
||||
|
||||
return true;
|
||||
>true : boolean
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndGeneric<T>(a: any): a is T {
|
||||
>fooWithTypeTypePredicateAndGeneric : <T>(a: any) => a is T
|
||||
>T : T
|
||||
>a : any
|
||||
>a : any
|
||||
>T : T
|
||||
|
||||
return true;
|
||||
>true : boolean
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndRestParam(a: any, ...rest): a is number {
|
||||
>fooWithTypeTypePredicateAndRestParam : (a: any, ...rest: any[]) => a is number
|
||||
>a : any
|
||||
>rest : any[]
|
||||
>a : any
|
||||
|
||||
return true;
|
||||
>true : boolean
|
||||
}
|
||||
|
||||
/** This comment should appear for nonExportedFoo*/
|
||||
function nonExportedFoo() {
|
||||
>nonExportedFoo : () => void
|
||||
|
|
|
@ -5,9 +5,9 @@ var maybeArray: number | number[];
|
|||
|
||||
if (Array.isArray(maybeArray)) {
|
||||
>Array.isArray(maybeArray) : boolean
|
||||
>Array.isArray : (arg: any) => boolean
|
||||
>Array.isArray : (arg: any) => arg is any[]
|
||||
>Array : ArrayConstructor
|
||||
>isArray : (arg: any) => boolean
|
||||
>isArray : (arg: any) => arg is any[]
|
||||
>maybeArray : number | number[]
|
||||
|
||||
maybeArray.length; // OK
|
||||
|
|
|
@ -23,19 +23,19 @@ class C extends A {
|
|||
}
|
||||
|
||||
declare function isA(p1: any): p1 is A;
|
||||
>isA : (p1: any) => boolean
|
||||
>isA : (p1: any) => p1 is A
|
||||
>p1 : any
|
||||
>p1 : any
|
||||
>A : A
|
||||
|
||||
declare function isB(p1: any): p1 is B;
|
||||
>isB : (p1: any) => boolean
|
||||
>isB : (p1: any) => p1 is B
|
||||
>p1 : any
|
||||
>p1 : any
|
||||
>B : B
|
||||
|
||||
declare function isC(p1: any): p1 is C;
|
||||
>isC : (p1: any) => boolean
|
||||
>isC : (p1: any) => p1 is C
|
||||
>p1 : any
|
||||
>p1 : any
|
||||
>C : C
|
||||
|
@ -55,7 +55,7 @@ var b: B;
|
|||
// Basic
|
||||
if (isC(a)) {
|
||||
>isC(a) : boolean
|
||||
>isC : (p1: any) => boolean
|
||||
>isC : (p1: any) => p1 is C
|
||||
>a : A
|
||||
|
||||
a.propC;
|
||||
|
@ -71,7 +71,7 @@ var subType: C;
|
|||
|
||||
if(isA(subType)) {
|
||||
>isA(subType) : boolean
|
||||
>isA : (p1: any) => boolean
|
||||
>isA : (p1: any) => p1 is A
|
||||
>subType : C
|
||||
|
||||
subType.propC;
|
||||
|
@ -88,7 +88,7 @@ var union: A | B;
|
|||
|
||||
if(isA(union)) {
|
||||
>isA(union) : boolean
|
||||
>isA : (p1: any) => boolean
|
||||
>isA : (p1: any) => p1 is A
|
||||
>union : A | B
|
||||
|
||||
union.propA;
|
||||
|
@ -111,7 +111,7 @@ interface I1 {
|
|||
// 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
|
||||
>isC_multipleParams : (p1: any, p2: any) => p1 is C
|
||||
>p1 : any
|
||||
>p2 : any
|
||||
>p1 : any
|
||||
|
@ -119,7 +119,7 @@ declare function isC_multipleParams(p1, p2): p1 is C;
|
|||
|
||||
if (isC_multipleParams(a, 0)) {
|
||||
>isC_multipleParams(a, 0) : boolean
|
||||
>isC_multipleParams : (p1: any, p2: any) => boolean
|
||||
>isC_multipleParams : (p1: any, p2: any) => p1 is C
|
||||
>a : A
|
||||
>0 : number
|
||||
|
||||
|
@ -131,10 +131,10 @@ if (isC_multipleParams(a, 0)) {
|
|||
|
||||
// Methods
|
||||
var obj: {
|
||||
>obj : { func1(p1: A): boolean; }
|
||||
>obj : { func1(p1: A): p1 is C; }
|
||||
|
||||
func1(p1: A): p1 is C;
|
||||
>func1 : (p1: A) => boolean
|
||||
>func1 : (p1: A) => p1 is C
|
||||
>p1 : A
|
||||
>A : A
|
||||
>p1 : any
|
||||
|
@ -144,7 +144,7 @@ class D {
|
|||
>D : D
|
||||
|
||||
method1(p1: A): p1 is C {
|
||||
>method1 : (p1: A) => boolean
|
||||
>method1 : (p1: A) => p1 is C
|
||||
>p1 : A
|
||||
>A : A
|
||||
>p1 : any
|
||||
|
@ -157,8 +157,8 @@ class D {
|
|||
|
||||
// Arrow function
|
||||
let f1 = (p1: A): p1 is C => false;
|
||||
>f1 : (p1: A) => boolean
|
||||
>(p1: A): p1 is C => false : (p1: A) => boolean
|
||||
>f1 : (p1: A) => p1 is C
|
||||
>(p1: A): p1 is C => false : (p1: A) => p1 is C
|
||||
>p1 : A
|
||||
>A : A
|
||||
>p1 : any
|
||||
|
@ -167,8 +167,8 @@ let f1 = (p1: A): p1 is C => false;
|
|||
|
||||
// Function type
|
||||
declare function f2(p1: (p1: A) => p1 is C);
|
||||
>f2 : (p1: (p1: A) => boolean) => any
|
||||
>p1 : (p1: A) => boolean
|
||||
>f2 : (p1: (p1: A) => p1 is C) => any
|
||||
>p1 : (p1: A) => p1 is C
|
||||
>p1 : A
|
||||
>A : A
|
||||
>p1 : any
|
||||
|
@ -177,8 +177,8 @@ declare function f2(p1: (p1: A) => p1 is 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
|
||||
>f2 : (p1: (p1: A) => p1 is C) => any
|
||||
>function(p1: A): p1 is C { return true;} : (p1: A) => p1 is C
|
||||
>p1 : A
|
||||
>A : A
|
||||
>p1 : any
|
||||
|
@ -198,21 +198,21 @@ acceptingBoolean(isA(a));
|
|||
>acceptingBoolean(isA(a)) : any
|
||||
>acceptingBoolean : (a: boolean) => any
|
||||
>isA(a) : boolean
|
||||
>isA : (p1: any) => boolean
|
||||
>isA : (p1: any) => p1 is A
|
||||
>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
|
||||
>acceptingTypeGuardFunction : (p1: (item: any) => item is A) => any
|
||||
>p1 : (item: any) => item is A
|
||||
>item : any
|
||||
>item : any
|
||||
>A : A
|
||||
|
||||
acceptingTypeGuardFunction(isA);
|
||||
>acceptingTypeGuardFunction(isA) : any
|
||||
>acceptingTypeGuardFunction : (p1: (item: any) => boolean) => any
|
||||
>isA : (p1: any) => boolean
|
||||
>acceptingTypeGuardFunction : (p1: (item: any) => item is A) => any
|
||||
>isA : (p1: any) => p1 is A
|
||||
|
||||
// Binary expressions
|
||||
let union2: C | B;
|
||||
|
@ -225,7 +225,7 @@ let union3: boolean | B = isA(union2) || union2;
|
|||
>B : B
|
||||
>isA(union2) || union2 : boolean | B
|
||||
>isA(union2) : boolean
|
||||
>isA : (p1: any) => boolean
|
||||
>isA : (p1: any) => p1 is A
|
||||
>union2 : B | C
|
||||
>union2 : B
|
||||
|
||||
|
|
|
@ -12,15 +12,15 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(46,56)
|
|||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(60,7): error TS2339: Property 'propB' does not exist on type 'A'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(65,7): error TS2339: Property 'propB' does not exist on type 'A'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(70,7): error TS2339: Property 'propB' does not exist on type 'A'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(75,46): error TS2345: Argument of type '(p1: any) => boolean' is not assignable to parameter of type '(p1: any) => boolean'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(75,46): error TS2345: Argument of type '(p1: any) => p1 is C' is not assignable to parameter of type '(p1: any) => p1 is B'.
|
||||
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(79,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(79,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => p1 is A'.
|
||||
Signature '(p1: any, p2: any): boolean' must have a type predicate.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(85,1): error TS2322: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => boolean'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(85,1): error TS2322: Type '(p1: any, p2: any) => p2 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'.
|
||||
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(91,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(91,1): error TS2322: Type '(p1: any, p2: any, p3: any) => p1 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,9): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,16): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(98,20): error TS1228: A type predicate is only allowed in return type position for functions and methods.
|
||||
|
@ -141,7 +141,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39
|
|||
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: Argument of type '(p1: any) => p1 is C' is not assignable to parameter of type '(p1: any) => p1 is B'.
|
||||
!!! error TS2345: Type predicate 'p1 is C' is not assignable to 'p1 is B'.
|
||||
!!! error TS2345: Type 'C' is not assignable to type 'B'.
|
||||
|
||||
|
@ -149,7 +149,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39
|
|||
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: Type '(p1: any, p2: any) => boolean' is not assignable to type '(p1: any, p2: any) => p1 is A'.
|
||||
!!! error TS2322: Signature '(p1: any, p2: any): boolean' must have a type predicate.
|
||||
return true;
|
||||
};
|
||||
|
@ -158,7 +158,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39
|
|||
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 '(p1: any, p2: any) => p2 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'.
|
||||
!!! 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;
|
||||
|
@ -168,7 +168,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(137,39
|
|||
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'.
|
||||
!!! error TS2322: Type '(p1: any, p2: any, p3: any) => p1 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'.
|
||||
return true;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,13 +23,13 @@ class C extends A {
|
|||
}
|
||||
|
||||
declare function isB(p1): p1 is B;
|
||||
>isB : (p1: any) => boolean
|
||||
>isB : (p1: any) => p1 is B
|
||||
>p1 : any
|
||||
>p1 : any
|
||||
>B : B
|
||||
|
||||
declare function isC(p1): p1 is C;
|
||||
>isC : (p1: any) => boolean
|
||||
>isC : (p1: any) => p1 is C
|
||||
>p1 : any
|
||||
>p1 : any
|
||||
>C : C
|
||||
|
@ -48,7 +48,7 @@ declare function funA<T>(p1: (p1) => 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
|
||||
>funB : <T>(p1: (p1: any) => T, p2: any) => p2 is T
|
||||
>T : T
|
||||
>p1 : (p1: any) => T
|
||||
>p1 : any
|
||||
|
@ -58,18 +58,18 @@ declare function funB<T>(p1: (p1) => T, p2: any): p2 is T;
|
|||
>T : T
|
||||
|
||||
declare function funC<T>(p1: (p1) => p1 is T): T;
|
||||
>funC : <T>(p1: (p1: any) => boolean) => T
|
||||
>funC : <T>(p1: (p1: any) => p1 is T) => T
|
||||
>T : T
|
||||
>p1 : (p1: any) => boolean
|
||||
>p1 : (p1: any) => p1 is T
|
||||
>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
|
||||
>funD : <T>(p1: (p1: any) => p1 is T, p2: any) => p2 is T
|
||||
>T : T
|
||||
>p1 : (p1: any) => boolean
|
||||
>p1 : (p1: any) => p1 is T
|
||||
>p1 : any
|
||||
>p1 : any
|
||||
>T : T
|
||||
|
@ -78,10 +78,10 @@ declare function funD<T>(p1: (p1) => p1 is T, p2: any): p2 is T;
|
|||
>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
|
||||
>funE : <T, U>(p1: (p1: any) => p1 is T, p2: U) => T
|
||||
>T : T
|
||||
>U : U
|
||||
>p1 : (p1: any) => boolean
|
||||
>p1 : (p1: any) => p1 is T
|
||||
>p1 : any
|
||||
>p1 : any
|
||||
>T : T
|
||||
|
@ -97,11 +97,11 @@ let test1: boolean = funA(isB);
|
|||
>test1 : boolean
|
||||
>funA(isB) : boolean
|
||||
>funA : <T>(p1: (p1: any) => T) => T
|
||||
>isB : (p1: any) => boolean
|
||||
>isB : (p1: any) => p1 is B
|
||||
|
||||
if (funB(retC, a)) {
|
||||
>funB(retC, a) : boolean
|
||||
>funB : <T>(p1: (p1: any) => T, p2: any) => boolean
|
||||
>funB : <T>(p1: (p1: any) => T, p2: any) => p2 is T
|
||||
>retC : (x: any) => C
|
||||
>a : A
|
||||
|
||||
|
@ -114,13 +114,13 @@ let test2: B = funC(isB);
|
|||
>test2 : B
|
||||
>B : B
|
||||
>funC(isB) : B
|
||||
>funC : <T>(p1: (p1: any) => boolean) => T
|
||||
>isB : (p1: any) => boolean
|
||||
>funC : <T>(p1: (p1: any) => p1 is T) => T
|
||||
>isB : (p1: any) => p1 is B
|
||||
|
||||
if (funD(isC, a)) {
|
||||
>funD(isC, a) : boolean
|
||||
>funD : <T>(p1: (p1: any) => boolean, p2: any) => boolean
|
||||
>isC : (p1: any) => boolean
|
||||
>funD : <T>(p1: (p1: any) => p1 is T, p2: any) => p2 is T
|
||||
>isC : (p1: any) => p1 is C
|
||||
>a : A
|
||||
|
||||
a.propC;
|
||||
|
@ -132,7 +132,7 @@ 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
|
||||
>funE : <T, U>(p1: (p1: any) => p1 is T, p2: U) => T
|
||||
>isB : (p1: any) => p1 is B
|
||||
>1 : number
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ var strOrNum: string | number;
|
|||
>strOrNum : string | number
|
||||
|
||||
function isC1(x: any): x is C1 {
|
||||
>isC1 : (x: any) => boolean
|
||||
>isC1 : (x: any) => x is C1
|
||||
>x : any
|
||||
>x : any
|
||||
>C1 : C1
|
||||
|
@ -39,7 +39,7 @@ function isC1(x: any): x is C1 {
|
|||
}
|
||||
|
||||
function isC2(x: any): x is C2 {
|
||||
>isC2 : (x: any) => boolean
|
||||
>isC2 : (x: any) => x is C2
|
||||
>x : any
|
||||
>x : any
|
||||
>C2 : C2
|
||||
|
@ -49,7 +49,7 @@ function isC2(x: any): x is C2 {
|
|||
}
|
||||
|
||||
function isD1(x: any): x is D1 {
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>x : any
|
||||
>x : any
|
||||
>D1 : D1
|
||||
|
@ -68,7 +68,7 @@ str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
|||
>str : string
|
||||
>isC1(c1Orc2) && c1Orc2.p1 : string
|
||||
>isC1(c1Orc2) : boolean
|
||||
>isC1 : (x: any) => boolean
|
||||
>isC1 : (x: any) => x is C1
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p1 : string
|
||||
>c1Orc2 : C1
|
||||
|
@ -79,7 +79,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
|||
>num : number
|
||||
>isC2(c1Orc2) && c1Orc2.p2 : number
|
||||
>isC2(c1Orc2) : boolean
|
||||
>isC2 : (x: any) => boolean
|
||||
>isC2 : (x: any) => x is C2
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p2 : number
|
||||
>c1Orc2 : C2
|
||||
|
@ -90,7 +90,7 @@ str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
|||
>str : string
|
||||
>isD1(c1Orc2) && c1Orc2.p1 : string
|
||||
>isD1(c1Orc2) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p1 : string
|
||||
>c1Orc2 : D1
|
||||
|
@ -101,7 +101,7 @@ num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
|||
>num : number
|
||||
>isD1(c1Orc2) && c1Orc2.p3 : number
|
||||
>isD1(c1Orc2) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p3 : number
|
||||
>c1Orc2 : D1
|
||||
|
@ -117,7 +117,7 @@ num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
|||
>num : number
|
||||
>isC2(c2Ord1) && c2Ord1.p2 : number
|
||||
>isC2(c2Ord1) : boolean
|
||||
>isC2 : (x: any) => boolean
|
||||
>isC2 : (x: any) => x is C2
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1.p2 : number
|
||||
>c2Ord1 : C2
|
||||
|
@ -128,7 +128,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
|||
>num : number
|
||||
>isD1(c2Ord1) && c2Ord1.p3 : number
|
||||
>isD1(c2Ord1) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1.p3 : number
|
||||
>c2Ord1 : D1
|
||||
|
@ -139,7 +139,7 @@ str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
|||
>str : string
|
||||
>isD1(c2Ord1) && c2Ord1.p1 : string
|
||||
>isD1(c2Ord1) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1.p1 : string
|
||||
>c2Ord1 : D1
|
||||
|
@ -151,7 +151,7 @@ var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
|||
>D1 : D1
|
||||
>isC1(c2Ord1) && c2Ord1 : D1
|
||||
>isC1(c2Ord1) : boolean
|
||||
>isC1 : (x: any) => boolean
|
||||
>isC1 : (x: any) => x is C1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1 : D1
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ var strOrNum: string | number;
|
|||
|
||||
|
||||
function isC1(x: any): x is C1 {
|
||||
>isC1 : (x: any) => boolean
|
||||
>isC1 : (x: any) => x is C1
|
||||
>x : any
|
||||
>x : any
|
||||
>C1 : C1
|
||||
|
@ -58,7 +58,7 @@ function isC1(x: any): x is C1 {
|
|||
}
|
||||
|
||||
function isC2(x: any): x is C2 {
|
||||
>isC2 : (x: any) => boolean
|
||||
>isC2 : (x: any) => x is C2
|
||||
>x : any
|
||||
>x : any
|
||||
>C2 : C2
|
||||
|
@ -68,7 +68,7 @@ function isC2(x: any): x is C2 {
|
|||
}
|
||||
|
||||
function isD1(x: any): x is D1 {
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>x : any
|
||||
>x : any
|
||||
>D1 : D1
|
||||
|
@ -99,7 +99,7 @@ str = isC1(c1Orc2) && c1Orc2.p1; // C1
|
|||
>str : string
|
||||
>isC1(c1Orc2) && c1Orc2.p1 : string
|
||||
>isC1(c1Orc2) : boolean
|
||||
>isC1 : (x: any) => boolean
|
||||
>isC1 : (x: any) => x is C1
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p1 : string
|
||||
>c1Orc2 : C1
|
||||
|
@ -110,7 +110,7 @@ num = isC2(c1Orc2) && c1Orc2.p2; // C2
|
|||
>num : number
|
||||
>isC2(c1Orc2) && c1Orc2.p2 : number
|
||||
>isC2(c1Orc2) : boolean
|
||||
>isC2 : (x: any) => boolean
|
||||
>isC2 : (x: any) => x is C2
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p2 : number
|
||||
>c1Orc2 : C2
|
||||
|
@ -121,7 +121,7 @@ str = isD1(c1Orc2) && c1Orc2.p1; // D1
|
|||
>str : string
|
||||
>isD1(c1Orc2) && c1Orc2.p1 : string
|
||||
>isD1(c1Orc2) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p1 : string
|
||||
>c1Orc2 : D1
|
||||
|
@ -132,7 +132,7 @@ num = isD1(c1Orc2) && c1Orc2.p3; // D1
|
|||
>num : number
|
||||
>isD1(c1Orc2) && c1Orc2.p3 : number
|
||||
>isD1(c1Orc2) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c1Orc2 : C1 | C2
|
||||
>c1Orc2.p3 : number
|
||||
>c1Orc2 : D1
|
||||
|
@ -148,7 +148,7 @@ num = isC2(c2Ord1) && c2Ord1.p2; // C2
|
|||
>num : number
|
||||
>isC2(c2Ord1) && c2Ord1.p2 : number
|
||||
>isC2(c2Ord1) : boolean
|
||||
>isC2 : (x: any) => boolean
|
||||
>isC2 : (x: any) => x is C2
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1.p2 : number
|
||||
>c2Ord1 : C2
|
||||
|
@ -159,7 +159,7 @@ num = isD1(c2Ord1) && c2Ord1.p3; // D1
|
|||
>num : number
|
||||
>isD1(c2Ord1) && c2Ord1.p3 : number
|
||||
>isD1(c2Ord1) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1.p3 : number
|
||||
>c2Ord1 : D1
|
||||
|
@ -170,7 +170,7 @@ str = isD1(c2Ord1) && c2Ord1.p1; // D1
|
|||
>str : string
|
||||
>isD1(c2Ord1) && c2Ord1.p1 : string
|
||||
>isD1(c2Ord1) : boolean
|
||||
>isD1 : (x: any) => boolean
|
||||
>isD1 : (x: any) => x is D1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1.p1 : string
|
||||
>c2Ord1 : D1
|
||||
|
@ -182,7 +182,7 @@ var r2: C2 | D1 = isC1(c2Ord1) && c2Ord1; // C2 | D1
|
|||
>D1 : D1
|
||||
>isC1(c2Ord1) && c2Ord1 : D1
|
||||
>isC1(c2Ord1) : boolean
|
||||
>isC1 : (x: any) => boolean
|
||||
>isC1 : (x: any) => x is C1
|
||||
>c2Ord1 : C2 | D1
|
||||
>c2Ord1 : D1
|
||||
|
||||
|
|
|
@ -28,6 +28,19 @@ export function fooWithSingleOverload(a: any) {
|
|||
return a;
|
||||
}
|
||||
|
||||
export function fooWithTypePredicate(a: any): a is number {
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypePredicateAndMulitpleParams(a: any, b: any, c: any): a is number {
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndGeneric<T>(a: any): a is T {
|
||||
return true;
|
||||
}
|
||||
export function fooWithTypeTypePredicateAndRestParam(a: any, ...rest): a is number {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** This comment should appear for nonExportedFoo*/
|
||||
function nonExportedFoo() {
|
||||
}
|
||||
|
|
20
tests/cases/fourslash/signatureHelpOnTypePredicates.ts
Normal file
20
tests/cases/fourslash/signatureHelpOnTypePredicates.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/// <reference path="fourslash.ts" />
|
||||
|
||||
//// function f1(a: any): a is number {}
|
||||
//// function f2<T>(a: any): a is T {}
|
||||
//// function f3(a: any, ...b): a is number {}
|
||||
//// f1(/*1*/)
|
||||
//// f2(/*2*/)
|
||||
//// f3(/*3*/)
|
||||
|
||||
goTo.marker("1");
|
||||
verify.signatureHelpCountIs(1);
|
||||
verify.currentSignatureHelpIs("f1(a: any): a is number");
|
||||
|
||||
goTo.marker("2");
|
||||
verify.signatureHelpCountIs(1);
|
||||
verify.currentSignatureHelpIs("f2<T>(a: any): a is T");
|
||||
|
||||
goTo.marker("3");
|
||||
verify.signatureHelpCountIs(1);
|
||||
verify.currentSignatureHelpIs("f3(a: any, ...b: any[]): a is number");
|
Loading…
Reference in a new issue