Compare commits
8 commits
main
...
vue-hacks-
Author | SHA1 | Date | |
---|---|---|---|
|
17173a6e6c | ||
|
32e75f71a3 | ||
|
f3a12d104f | ||
|
6fd5e1bab8 | ||
|
56d18353c6 | ||
|
613aead278 | ||
|
9558c210f4 | ||
|
99743dfdd5 |
|
@ -3504,7 +3504,12 @@ namespace ts {
|
||||||
return isPrivateWithinAmbient(memberDeclaration);
|
return isPrivateWithinAmbient(memberDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeOfVariableOrParameterOrProperty(symbol: Symbol): Type {
|
function getTypeOfVariableOrParameterOrProperty(symbol: Symbol, crazy?: boolean): Type {
|
||||||
|
const declaration = symbol.valueDeclaration;
|
||||||
|
if (crazy && declaration.kind === SyntaxKind.Parameter && (declaration as ParameterDeclaration).contextualType) {
|
||||||
|
// TODO: Doesn't widen of course
|
||||||
|
return getTypeFromTypeNode((declaration as ParameterDeclaration).contextualType);
|
||||||
|
}
|
||||||
const links = getSymbolLinks(symbol);
|
const links = getSymbolLinks(symbol);
|
||||||
if (!links.type) {
|
if (!links.type) {
|
||||||
// Handle prototype property
|
// Handle prototype property
|
||||||
|
@ -3512,7 +3517,6 @@ namespace ts {
|
||||||
return links.type = getTypeOfPrototypeProperty(symbol);
|
return links.type = getTypeOfPrototypeProperty(symbol);
|
||||||
}
|
}
|
||||||
// Handle catch clause variables
|
// Handle catch clause variables
|
||||||
const declaration = symbol.valueDeclaration;
|
|
||||||
if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
|
if (isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
|
||||||
return links.type = anyType;
|
return links.type = anyType;
|
||||||
}
|
}
|
||||||
|
@ -3695,13 +3699,16 @@ namespace ts {
|
||||||
return links.type;
|
return links.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeOfInstantiatedSymbol(symbol: Symbol): Type {
|
function getTypeOfInstantiatedSymbol(symbol: Symbol, crazy?: boolean): Type {
|
||||||
const links = getSymbolLinks(symbol);
|
const links = getSymbolLinks(symbol);
|
||||||
|
if (crazy) {
|
||||||
|
return instantiateType(getTypeOfSymbol(links.target, crazy), links.mapper);
|
||||||
|
}
|
||||||
if (!links.type) {
|
if (!links.type) {
|
||||||
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
let type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
|
let type = instantiateType(getTypeOfSymbol(links.target, crazy), links.mapper);
|
||||||
if (!popTypeResolution()) {
|
if (!popTypeResolution()) {
|
||||||
type = reportCircularityError(symbol);
|
type = reportCircularityError(symbol);
|
||||||
}
|
}
|
||||||
|
@ -3725,12 +3732,12 @@ namespace ts {
|
||||||
return anyType;
|
return anyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeOfSymbol(symbol: Symbol): Type {
|
function getTypeOfSymbol(symbol: Symbol, crazy?: boolean): Type {
|
||||||
if (symbol.flags & SymbolFlags.Instantiated) {
|
if (symbol.flags & SymbolFlags.Instantiated) {
|
||||||
return getTypeOfInstantiatedSymbol(symbol);
|
return getTypeOfInstantiatedSymbol(symbol, crazy);
|
||||||
}
|
}
|
||||||
if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) {
|
if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) {
|
||||||
return getTypeOfVariableOrParameterOrProperty(symbol);
|
return getTypeOfVariableOrParameterOrProperty(symbol, crazy);
|
||||||
}
|
}
|
||||||
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
|
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
|
||||||
return getTypeOfFuncClassEnumModule(symbol);
|
return getTypeOfFuncClassEnumModule(symbol);
|
||||||
|
@ -4937,6 +4944,10 @@ namespace ts {
|
||||||
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
|
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getApparentTypeOfReturnType(type: ReturnType) {
|
||||||
|
return type.resolvedApparentType || (type.resolvedApparentType = getReturnType(getApparentType(type.type)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a type parameter, return the base constraint of the type parameter. For the string, number,
|
* For a type parameter, return the base constraint of the type parameter. For the string, number,
|
||||||
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
|
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
|
||||||
|
@ -4945,6 +4956,7 @@ namespace ts {
|
||||||
function getApparentType(type: Type): Type {
|
function getApparentType(type: Type): Type {
|
||||||
const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(<TypeVariable>type) || emptyObjectType : type;
|
const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(<TypeVariable>type) || emptyObjectType : type;
|
||||||
return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
|
return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
|
||||||
|
t.flags & TypeFlags.Return ? getApparentTypeOfReturnType(<ReturnType>t) :
|
||||||
t.flags & TypeFlags.StringLike ? globalStringType :
|
t.flags & TypeFlags.StringLike ? globalStringType :
|
||||||
t.flags & TypeFlags.NumberLike ? globalNumberType :
|
t.flags & TypeFlags.NumberLike ? globalNumberType :
|
||||||
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
|
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
|
||||||
|
@ -6188,6 +6200,29 @@ namespace ts {
|
||||||
return links.resolvedType;
|
return links.resolvedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTypeFromReturnOperatorNode(node: ReturnOperatorNode) {
|
||||||
|
const links = getNodeLinks(node);
|
||||||
|
if (!links.resolvedType) {
|
||||||
|
links.resolvedType = getReturnType(getTypeFromTypeNode(node.type));
|
||||||
|
}
|
||||||
|
return links.resolvedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReturnType(type: Type): Type {
|
||||||
|
if (maybeTypeOfKind(type, TypeFlags.TypeVariable)) {
|
||||||
|
return getReturnTypeForGenericType(type as TypeVariable | UnionOrIntersectionType);
|
||||||
|
}
|
||||||
|
return getUnionType(map(getSignaturesOfType(type, SignatureKind.Call), getReturnTypeOfSignature));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReturnTypeForGenericType(type: TypeVariable | UnionOrIntersectionType): Type {
|
||||||
|
if (!type.resolvedReturnType) {
|
||||||
|
type.resolvedReturnType = <ReturnType>createType(TypeFlags.Return);
|
||||||
|
type.resolvedReturnType.type = type;
|
||||||
|
}
|
||||||
|
return type.resolvedReturnType;
|
||||||
|
}
|
||||||
|
|
||||||
function createIndexedAccessType(objectType: Type, indexType: Type) {
|
function createIndexedAccessType(objectType: Type, indexType: Type) {
|
||||||
const type = <IndexedAccessType>createType(TypeFlags.IndexedAccess);
|
const type = <IndexedAccessType>createType(TypeFlags.IndexedAccess);
|
||||||
type.objectType = objectType;
|
type.objectType = objectType;
|
||||||
|
@ -6595,7 +6630,9 @@ namespace ts {
|
||||||
case SyntaxKind.JSDocFunctionType:
|
case SyntaxKind.JSDocFunctionType:
|
||||||
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
|
||||||
case SyntaxKind.TypeOperator:
|
case SyntaxKind.TypeOperator:
|
||||||
return getTypeFromTypeOperatorNode(<TypeOperatorNode>node);
|
return getTypeFromTypeOperatorNode(node as TypeOperatorNode);
|
||||||
|
case SyntaxKind.ReturnOperator:
|
||||||
|
return getTypeFromReturnOperatorNode(node as ReturnOperatorNode);
|
||||||
case SyntaxKind.IndexedAccessType:
|
case SyntaxKind.IndexedAccessType:
|
||||||
return getTypeFromIndexedAccessTypeNode(<IndexedAccessTypeNode>node);
|
return getTypeFromIndexedAccessTypeNode(<IndexedAccessTypeNode>node);
|
||||||
case SyntaxKind.MappedType:
|
case SyntaxKind.MappedType:
|
||||||
|
@ -6962,6 +6999,9 @@ namespace ts {
|
||||||
if (type.flags & TypeFlags.Index) {
|
if (type.flags & TypeFlags.Index) {
|
||||||
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
return getIndexType(instantiateType((<IndexType>type).type, mapper));
|
||||||
}
|
}
|
||||||
|
if (type.flags & TypeFlags.Return) {
|
||||||
|
return getReturnType(instantiateType((<ReturnType>type).type, mapper));
|
||||||
|
}
|
||||||
if (type.flags & TypeFlags.IndexedAccess) {
|
if (type.flags & TypeFlags.IndexedAccess) {
|
||||||
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
|
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
|
||||||
}
|
}
|
||||||
|
@ -9040,7 +9080,7 @@ namespace ts {
|
||||||
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
|
// We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type
|
||||||
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
|
// parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X.
|
||||||
inferFromTypes(getIndexType(source), constraintType);
|
inferFromTypes(getIndexType(source), constraintType);
|
||||||
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
|
inferFromTypes(getUnionType(map(getPropertiesOfType(source), p => getTypeOfSymbol(p))), getTemplateTypeFromMappedType(<MappedType>target));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11229,7 +11269,7 @@ namespace ts {
|
||||||
const argIndex = indexOf(args, arg);
|
const argIndex = indexOf(args, arg);
|
||||||
if (argIndex >= 0) {
|
if (argIndex >= 0) {
|
||||||
const signature = getResolvedOrAnySignature(callTarget);
|
const signature = getResolvedOrAnySignature(callTarget);
|
||||||
return getTypeAtPosition(signature, argIndex);
|
return getSpecialContextualTypeAtPosition(signature, argIndex);
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -13064,7 +13104,7 @@ namespace ts {
|
||||||
// If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
|
// If the effective argument is 'undefined', then it is an argument that is present but is synthetic.
|
||||||
if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
|
if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) {
|
||||||
// Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
|
// Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter)
|
||||||
const paramType = getTypeAtPosition(signature, i);
|
const paramType = getSpecialContextualTypeAtPosition(signature, i);
|
||||||
let argType = getEffectiveArgumentType(node, i);
|
let argType = getEffectiveArgumentType(node, i);
|
||||||
|
|
||||||
// If the effective argument type is 'undefined', there is no synthetic type
|
// If the effective argument type is 'undefined', there is no synthetic type
|
||||||
|
@ -14088,8 +14128,8 @@ namespace ts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTypeOfParameter(symbol: Symbol) {
|
function getTypeOfParameter(symbol: Symbol, crazy?: boolean) {
|
||||||
const type = getTypeOfSymbol(symbol);
|
const type = getTypeOfSymbol(symbol, crazy);
|
||||||
if (strictNullChecks) {
|
if (strictNullChecks) {
|
||||||
const declaration = symbol.valueDeclaration;
|
const declaration = symbol.valueDeclaration;
|
||||||
if (declaration && (<VariableLikeDeclaration>declaration).initializer) {
|
if (declaration && (<VariableLikeDeclaration>declaration).initializer) {
|
||||||
|
@ -14099,6 +14139,12 @@ namespace ts {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSpecialContextualTypeAtPosition(signature: Signature, pos: number): Type {
|
||||||
|
return signature.hasRestParameter ?
|
||||||
|
pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos], /*crazy*/ true) : getRestTypeOfSignature(signature) :
|
||||||
|
pos < signature.parameters.length ? getTypeOfParameter(signature.parameters[pos], /*crazy*/ true) : anyType;
|
||||||
|
}
|
||||||
|
|
||||||
function getTypeAtPosition(signature: Signature, pos: number): Type {
|
function getTypeAtPosition(signature: Signature, pos: number): Type {
|
||||||
return signature.hasRestParameter ?
|
return signature.hasRestParameter ?
|
||||||
pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
|
pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos]) : getRestTypeOfSignature(signature) :
|
||||||
|
@ -15751,7 +15797,18 @@ namespace ts {
|
||||||
|
|
||||||
checkTypeParameters(node.typeParameters);
|
checkTypeParameters(node.typeParameters);
|
||||||
|
|
||||||
forEach(node.parameters, checkParameter);
|
const isObjectLiteralMethodWithThis = isObjectLiteralMethod(node) &&
|
||||||
|
node.parameters &&
|
||||||
|
node.parameters.length &&
|
||||||
|
parameterIsThisKeyword(node.parameters[0]);
|
||||||
|
if (isObjectLiteralMethodWithThis) {
|
||||||
|
// defer checking on first one
|
||||||
|
checkNodeDeferred(node.parameters[0]); // .. this will surely work ..
|
||||||
|
forEach(node.parameters.slice(1), checkParameter);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
forEach(node.parameters, checkParameter);
|
||||||
|
}
|
||||||
|
|
||||||
if (node.type) {
|
if (node.type) {
|
||||||
checkSourceElement(node.type);
|
checkSourceElement(node.type);
|
||||||
|
|
|
@ -89,6 +89,7 @@ namespace ts {
|
||||||
visitNode(cbNode, (<VariableLikeDeclaration>node).name) ||
|
visitNode(cbNode, (<VariableLikeDeclaration>node).name) ||
|
||||||
visitNode(cbNode, (<VariableLikeDeclaration>node).questionToken) ||
|
visitNode(cbNode, (<VariableLikeDeclaration>node).questionToken) ||
|
||||||
visitNode(cbNode, (<VariableLikeDeclaration>node).type) ||
|
visitNode(cbNode, (<VariableLikeDeclaration>node).type) ||
|
||||||
|
visitNode(cbNode, (<ParameterDeclaration>node).contextualType) ||
|
||||||
visitNode(cbNode, (<VariableLikeDeclaration>node).initializer);
|
visitNode(cbNode, (<VariableLikeDeclaration>node).initializer);
|
||||||
case SyntaxKind.FunctionType:
|
case SyntaxKind.FunctionType:
|
||||||
case SyntaxKind.ConstructorType:
|
case SyntaxKind.ConstructorType:
|
||||||
|
@ -138,6 +139,8 @@ namespace ts {
|
||||||
case SyntaxKind.ParenthesizedType:
|
case SyntaxKind.ParenthesizedType:
|
||||||
case SyntaxKind.TypeOperator:
|
case SyntaxKind.TypeOperator:
|
||||||
return visitNode(cbNode, (<ParenthesizedTypeNode | TypeOperatorNode>node).type);
|
return visitNode(cbNode, (<ParenthesizedTypeNode | TypeOperatorNode>node).type);
|
||||||
|
case SyntaxKind.ReturnOperator:
|
||||||
|
return visitNode(cbNode, (<ReturnOperatorNode>node).type);
|
||||||
case SyntaxKind.IndexedAccessType:
|
case SyntaxKind.IndexedAccessType:
|
||||||
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
|
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
|
||||||
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
|
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
|
||||||
|
@ -2115,7 +2118,6 @@ namespace ts {
|
||||||
if (parseOptional(SyntaxKind.ColonToken)) {
|
if (parseOptional(SyntaxKind.ColonToken)) {
|
||||||
return parseType();
|
return parseType();
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2152,6 +2154,9 @@ namespace ts {
|
||||||
|
|
||||||
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
|
||||||
node.type = parseParameterType();
|
node.type = parseParameterType();
|
||||||
|
if (parseOptional(SyntaxKind.AsKeyword)) {
|
||||||
|
node.contextualType = parseType();
|
||||||
|
}
|
||||||
node.initializer = parseBindingElementInitializer(/*inParameter*/ true);
|
node.initializer = parseBindingElementInitializer(/*inParameter*/ true);
|
||||||
|
|
||||||
// Do not check for initializers in an ambient context for parameters. This is not
|
// Do not check for initializers in an ambient context for parameters. This is not
|
||||||
|
@ -2611,7 +2616,23 @@ namespace ts {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword) {
|
function parseReturnOperator(operator: SyntaxKind.ReturnKeyword): TypeNode {
|
||||||
|
const node = <ReturnOperatorNode>createNode(SyntaxKind.ReturnOperator);
|
||||||
|
parseExpected(operator);
|
||||||
|
node.operator = operator;
|
||||||
|
node.type = parseReturnOperatorOrHigher();
|
||||||
|
return finishNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseReturnOperatorOrHigher(): TypeNode {
|
||||||
|
switch (token()) {
|
||||||
|
case SyntaxKind.ReturnKeyword:
|
||||||
|
return parseReturnOperator(SyntaxKind.ReturnKeyword);
|
||||||
|
}
|
||||||
|
return parseTypeOperatorOrHigher();
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword) {
|
||||||
const node = <TypeOperatorNode>createNode(SyntaxKind.TypeOperator);
|
const node = <TypeOperatorNode>createNode(SyntaxKind.TypeOperator);
|
||||||
parseExpected(operator);
|
parseExpected(operator);
|
||||||
node.operator = operator;
|
node.operator = operator;
|
||||||
|
@ -2644,7 +2665,7 @@ namespace ts {
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseIntersectionTypeOrHigher(): TypeNode {
|
function parseIntersectionTypeOrHigher(): TypeNode {
|
||||||
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseTypeOperatorOrHigher, SyntaxKind.AmpersandToken);
|
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseReturnOperatorOrHigher, SyntaxKind.AmpersandToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseUnionTypeOrHigher(): TypeNode {
|
function parseUnionTypeOrHigher(): TypeNode {
|
||||||
|
|
|
@ -238,6 +238,7 @@
|
||||||
ParenthesizedType,
|
ParenthesizedType,
|
||||||
ThisType,
|
ThisType,
|
||||||
TypeOperator,
|
TypeOperator,
|
||||||
|
ReturnOperator,
|
||||||
IndexedAccessType,
|
IndexedAccessType,
|
||||||
MappedType,
|
MappedType,
|
||||||
LiteralType,
|
LiteralType,
|
||||||
|
@ -665,6 +666,7 @@
|
||||||
name: BindingName; // Declared parameter name
|
name: BindingName; // Declared parameter name
|
||||||
questionToken?: QuestionToken; // Present on optional parameter
|
questionToken?: QuestionToken; // Present on optional parameter
|
||||||
type?: TypeNode; // Optional type annotation
|
type?: TypeNode; // Optional type annotation
|
||||||
|
contextualType?: TypeNode; // Super-optional contextual type annotation
|
||||||
initializer?: Expression; // Optional initializer
|
initializer?: Expression; // Optional initializer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,6 +919,12 @@
|
||||||
type: TypeNode;
|
type: TypeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ReturnOperatorNode extends TypeNode {
|
||||||
|
kind: SyntaxKind.ReturnOperator;
|
||||||
|
operator: SyntaxKind.ReturnKeyword;
|
||||||
|
type: TypeNode;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IndexedAccessTypeNode extends TypeNode {
|
export interface IndexedAccessTypeNode extends TypeNode {
|
||||||
kind: SyntaxKind.IndexedAccessType;
|
kind: SyntaxKind.IndexedAccessType;
|
||||||
objectType: TypeNode;
|
objectType: TypeNode;
|
||||||
|
@ -2823,6 +2831,7 @@
|
||||||
/* @internal */
|
/* @internal */
|
||||||
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
|
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
|
||||||
NonPrimitive = 1 << 24, // intrinsic object type
|
NonPrimitive = 1 << 24, // intrinsic object type
|
||||||
|
Return = 1 << 25, // Return type of callable (never for uncallable types)
|
||||||
|
|
||||||
/* @internal */
|
/* @internal */
|
||||||
Nullable = Undefined | Null,
|
Nullable = Undefined | Null,
|
||||||
|
@ -2963,6 +2972,8 @@
|
||||||
/* @internal */
|
/* @internal */
|
||||||
resolvedIndexType: IndexType;
|
resolvedIndexType: IndexType;
|
||||||
/* @internal */
|
/* @internal */
|
||||||
|
resolvedReturnType: ReturnType;
|
||||||
|
/* @internal */
|
||||||
resolvedBaseConstraint: Type;
|
resolvedBaseConstraint: Type;
|
||||||
/* @internal */
|
/* @internal */
|
||||||
couldContainTypeVariables: boolean;
|
couldContainTypeVariables: boolean;
|
||||||
|
@ -3030,6 +3041,8 @@
|
||||||
resolvedBaseConstraint: Type;
|
resolvedBaseConstraint: Type;
|
||||||
/* @internal */
|
/* @internal */
|
||||||
resolvedIndexType: IndexType;
|
resolvedIndexType: IndexType;
|
||||||
|
/* @internal */
|
||||||
|
resolvedReturnType: ReturnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type parameters (TypeFlags.TypeParameter)
|
// Type parameters (TypeFlags.TypeParameter)
|
||||||
|
@ -3056,6 +3069,13 @@
|
||||||
type: TypeVariable | UnionOrIntersectionType;
|
type: TypeVariable | UnionOrIntersectionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return T types (TypeFlags.Return)
|
||||||
|
export interface ReturnType extends Type {
|
||||||
|
type: TypeVariable | UnionOrIntersectionType;
|
||||||
|
/* @internal */
|
||||||
|
resolvedApparentType: Type;
|
||||||
|
}
|
||||||
|
|
||||||
export const enum SignatureKind {
|
export const enum SignatureKind {
|
||||||
Call,
|
Call,
|
||||||
Construct,
|
Construct,
|
||||||
|
|
33
tests/baselines/reference/recursion.js
Normal file
33
tests/baselines/reference/recursion.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
//// [recursion.ts]
|
||||||
|
let o = {
|
||||||
|
p: 12,
|
||||||
|
m(this: typeof o) {
|
||||||
|
let x = this.m(); // x: number
|
||||||
|
let y = this.p; // y: number
|
||||||
|
return this.p;
|
||||||
|
},
|
||||||
|
m2() {
|
||||||
|
return this.m() // this: any since it has no annotation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = o.m() // x: number
|
||||||
|
let y = o.m2() // y: any
|
||||||
|
let p = o.p // p: number
|
||||||
|
|
||||||
|
|
||||||
|
//// [recursion.js]
|
||||||
|
var o = {
|
||||||
|
p: 12,
|
||||||
|
m: function () {
|
||||||
|
var x = this.m(); // x: number
|
||||||
|
var y = this.p; // y: number
|
||||||
|
return this.p;
|
||||||
|
},
|
||||||
|
m2: function () {
|
||||||
|
return this.m(); // this: any since it has no annotation
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var x = o.m(); // x: number
|
||||||
|
var y = o.m2(); // y: any
|
||||||
|
var p = o.p; // p: number
|
55
tests/baselines/reference/recursion.symbols
Normal file
55
tests/baselines/reference/recursion.symbols
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
=== tests/cases/compiler/recursion.ts ===
|
||||||
|
let o = {
|
||||||
|
>o : Symbol(o, Decl(recursion.ts, 0, 3))
|
||||||
|
|
||||||
|
p: 12,
|
||||||
|
>p : Symbol(p, Decl(recursion.ts, 0, 9))
|
||||||
|
|
||||||
|
m(this: typeof o) {
|
||||||
|
>m : Symbol(m, Decl(recursion.ts, 1, 10))
|
||||||
|
>this : Symbol(this, Decl(recursion.ts, 2, 6))
|
||||||
|
>o : Symbol(o, Decl(recursion.ts, 0, 3))
|
||||||
|
|
||||||
|
let x = this.m(); // x: number
|
||||||
|
>x : Symbol(x, Decl(recursion.ts, 3, 11))
|
||||||
|
>this.m : Symbol(m, Decl(recursion.ts, 1, 10))
|
||||||
|
>this : Symbol(this, Decl(recursion.ts, 2, 6))
|
||||||
|
>m : Symbol(m, Decl(recursion.ts, 1, 10))
|
||||||
|
|
||||||
|
let y = this.p; // y: number
|
||||||
|
>y : Symbol(y, Decl(recursion.ts, 4, 11))
|
||||||
|
>this.p : Symbol(p, Decl(recursion.ts, 0, 9))
|
||||||
|
>this : Symbol(this, Decl(recursion.ts, 2, 6))
|
||||||
|
>p : Symbol(p, Decl(recursion.ts, 0, 9))
|
||||||
|
|
||||||
|
return this.p;
|
||||||
|
>this.p : Symbol(p, Decl(recursion.ts, 0, 9))
|
||||||
|
>this : Symbol(this, Decl(recursion.ts, 2, 6))
|
||||||
|
>p : Symbol(p, Decl(recursion.ts, 0, 9))
|
||||||
|
|
||||||
|
},
|
||||||
|
m2() {
|
||||||
|
>m2 : Symbol(m2, Decl(recursion.ts, 6, 6))
|
||||||
|
|
||||||
|
return this.m() // this: any since it has no annotation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = o.m() // x: number
|
||||||
|
>x : Symbol(x, Decl(recursion.ts, 12, 3))
|
||||||
|
>o.m : Symbol(m, Decl(recursion.ts, 1, 10))
|
||||||
|
>o : Symbol(o, Decl(recursion.ts, 0, 3))
|
||||||
|
>m : Symbol(m, Decl(recursion.ts, 1, 10))
|
||||||
|
|
||||||
|
let y = o.m2() // y: any
|
||||||
|
>y : Symbol(y, Decl(recursion.ts, 13, 3))
|
||||||
|
>o.m2 : Symbol(m2, Decl(recursion.ts, 6, 6))
|
||||||
|
>o : Symbol(o, Decl(recursion.ts, 0, 3))
|
||||||
|
>m2 : Symbol(m2, Decl(recursion.ts, 6, 6))
|
||||||
|
|
||||||
|
let p = o.p // p: number
|
||||||
|
>p : Symbol(p, Decl(recursion.ts, 14, 3))
|
||||||
|
>o.p : Symbol(p, Decl(recursion.ts, 0, 9))
|
||||||
|
>o : Symbol(o, Decl(recursion.ts, 0, 3))
|
||||||
|
>p : Symbol(p, Decl(recursion.ts, 0, 9))
|
||||||
|
|
64
tests/baselines/reference/recursion.types
Normal file
64
tests/baselines/reference/recursion.types
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
=== tests/cases/compiler/recursion.ts ===
|
||||||
|
let o = {
|
||||||
|
>o : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>{ p: 12, m(this: typeof o) { let x = this.m(); // x: number let y = this.p; // y: number return this.p; }, m2() { return this.m() // this: any since it has no annotation }} : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
|
||||||
|
p: 12,
|
||||||
|
>p : number
|
||||||
|
>12 : 12
|
||||||
|
|
||||||
|
m(this: typeof o) {
|
||||||
|
>m : (this: { p: number; m(this: any): number; m2(): any; }) => number
|
||||||
|
>this : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>o : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
|
||||||
|
let x = this.m(); // x: number
|
||||||
|
>x : number
|
||||||
|
>this.m() : number
|
||||||
|
>this.m : (this: { p: number; m(this: any): number; m2(): any; }) => number
|
||||||
|
>this : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>m : (this: { p: number; m(this: any): number; m2(): any; }) => number
|
||||||
|
|
||||||
|
let y = this.p; // y: number
|
||||||
|
>y : number
|
||||||
|
>this.p : number
|
||||||
|
>this : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>p : number
|
||||||
|
|
||||||
|
return this.p;
|
||||||
|
>this.p : number
|
||||||
|
>this : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>p : number
|
||||||
|
|
||||||
|
},
|
||||||
|
m2() {
|
||||||
|
>m2 : () => any
|
||||||
|
|
||||||
|
return this.m() // this: any since it has no annotation
|
||||||
|
>this.m() : any
|
||||||
|
>this.m : any
|
||||||
|
>this : any
|
||||||
|
>m : any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = o.m() // x: number
|
||||||
|
>x : number
|
||||||
|
>o.m() : number
|
||||||
|
>o.m : (this: { p: number; m(this: any): number; m2(): any; }) => number
|
||||||
|
>o : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>m : (this: { p: number; m(this: any): number; m2(): any; }) => number
|
||||||
|
|
||||||
|
let y = o.m2() // y: any
|
||||||
|
>y : any
|
||||||
|
>o.m2() : any
|
||||||
|
>o.m2 : () => any
|
||||||
|
>o : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>m2 : () => any
|
||||||
|
|
||||||
|
let p = o.p // p: number
|
||||||
|
>p : number
|
||||||
|
>o.p : number
|
||||||
|
>o : { p: number; m(this: any): number; m2(): any; }
|
||||||
|
>p : number
|
||||||
|
|
85
tests/cases/compiler/recursion.ts
Normal file
85
tests/cases/compiler/recursion.ts
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// TODO: Assignability error when the contextual type of data is `U & V`
|
||||||
|
declare function create<U, V, W>(
|
||||||
|
x: {data: U, methods: V, properties: W} as
|
||||||
|
{
|
||||||
|
data: U,
|
||||||
|
methods: { [s: string]: (this: U & V & Propertise<W>, ...args: any[]) => any },
|
||||||
|
properties: { [s: string]: (this: U & V & Propertise<W>, ...args: any[]) => any }
|
||||||
|
}): U & V & Propertise<W>;
|
||||||
|
let vue = create({
|
||||||
|
data: { x: 1 },
|
||||||
|
methods: {
|
||||||
|
m() { return 12 /*this.x*/ },
|
||||||
|
m2() { return this.m() },
|
||||||
|
m3() { return this.p },
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
p() { return 'foo' /*this.x*/ },
|
||||||
|
p2() { return this.p },
|
||||||
|
p3() { return this.m() },
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
Problem: you need to fix U and V but also make them provide a contextual type that includes the *whole* type.
|
||||||
|
But transformed, so the *whole* *transformed* type.
|
||||||
|
|
||||||
|
So here's an idea: an in and out type. One is used for type inference (to)
|
||||||
|
and the other is used for contextual typing. Plus maybe type inference from? Not sure about that one.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
type Propertise<T> = { [K in keyof T]: return T[K] };
|
||||||
|
type ExplicitVue<T extends { data, methods, properties }> = T['data'] & T['methods'] & Propertise<T['properties']>;
|
||||||
|
|
||||||
|
let options = {
|
||||||
|
data: {
|
||||||
|
a: 12,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
m1(this: ExplicitVue<typeof options>) {
|
||||||
|
this.a;
|
||||||
|
this.m2();
|
||||||
|
return this.a + this.p.length;
|
||||||
|
},
|
||||||
|
m2(this: ExplicitVue<typeof options>) {
|
||||||
|
return this.m1();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
p() { return 'foo' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let app: ExplicitVue<typeof options>;
|
||||||
|
/*interface Vue<T> {
|
||||||
|
data: any,
|
||||||
|
methods: { [s: string]: (this: ExplicitVue, ...args: any[]) => any },
|
||||||
|
properties: Propertise<{ [s: string]: (this: ExplicitVue, ...args: any[]) => any }>
|
||||||
|
}
|
||||||
|
declare function create<T>(options: Vue<T>): Vue<T>;
|
||||||
|
create({
|
||||||
|
data: { a: 12 },
|
||||||
|
methods: {
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
let o = {
|
||||||
|
p: 12,
|
||||||
|
m(this: typeof o) {
|
||||||
|
let x = this.m(); // x: number
|
||||||
|
let y = this.p; // y: number
|
||||||
|
return this.p;
|
||||||
|
},
|
||||||
|
m2() {
|
||||||
|
return this.m() // this: any since it has no annotation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = o.m() // x: number
|
||||||
|
let y = o.m2() // y: any
|
||||||
|
let p = o.p // p: number
|
||||||
|
|
||||||
|
*/
|
Loading…
Reference in a new issue