mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
+40
-58
@@ -250,7 +250,7 @@ namespace ts {
|
||||
getTypeOfSymbol,
|
||||
getResolvedSymbol,
|
||||
getIndexTypeOfStructuredType,
|
||||
getConstraintFromTypeParameter,
|
||||
getConstraintOfTypeParameter,
|
||||
getFirstIdentifier,
|
||||
),
|
||||
getAmbientModules,
|
||||
@@ -3715,7 +3715,7 @@ namespace ts {
|
||||
return createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
|
||||
}
|
||||
|
||||
function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintFromTypeParameter(type)): TypeParameterDeclaration {
|
||||
function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter(type)): TypeParameterDeclaration {
|
||||
const constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
|
||||
return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
|
||||
}
|
||||
@@ -4363,29 +4363,23 @@ namespace ts {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
function hasType(target: TypeSystemEntity, propertyName: TypeSystemPropertyName): boolean {
|
||||
if (propertyName === TypeSystemPropertyName.Type) {
|
||||
return !!getSymbolLinks(<Symbol>target).type;
|
||||
switch (propertyName) {
|
||||
case TypeSystemPropertyName.Type:
|
||||
return !!getSymbolLinks(<Symbol>target).type;
|
||||
case TypeSystemPropertyName.DeclaredType:
|
||||
return !!getSymbolLinks(<Symbol>target).declaredType;
|
||||
case TypeSystemPropertyName.ResolvedBaseConstructorType:
|
||||
return !!(<InterfaceType>target).resolvedBaseConstructorType;
|
||||
case TypeSystemPropertyName.ResolvedReturnType:
|
||||
return !!(<Signature>target).resolvedReturnType;
|
||||
case TypeSystemPropertyName.ImmediateBaseConstraint:
|
||||
return !!(<Type>target).immediateBaseConstraint;
|
||||
}
|
||||
if (propertyName === TypeSystemPropertyName.DeclaredType) {
|
||||
return !!getSymbolLinks(<Symbol>target).declaredType;
|
||||
}
|
||||
if (propertyName === TypeSystemPropertyName.ResolvedBaseConstructorType) {
|
||||
return !!(<InterfaceType>target).resolvedBaseConstructorType;
|
||||
}
|
||||
if (propertyName === TypeSystemPropertyName.ResolvedReturnType) {
|
||||
return !!(<Signature>target).resolvedReturnType;
|
||||
}
|
||||
if (propertyName === TypeSystemPropertyName.ImmediateBaseConstraint) {
|
||||
const bc = (<Type>target).immediateBaseConstraint;
|
||||
return !!bc && bc !== circularConstraintType;
|
||||
}
|
||||
|
||||
return Debug.fail("Unhandled TypeSystemPropertyName " + propertyName);
|
||||
return Debug.assertNever(propertyName);
|
||||
}
|
||||
|
||||
// Pop an entry from the type resolution stack and return its associated result value. The result value will
|
||||
@@ -6936,21 +6930,12 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type: Type) {
|
||||
function getBaseConstraintOfType(type: Type): Type | undefined {
|
||||
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
|
||||
const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
|
||||
if (constraint !== noConstraintType && constraint !== circularConstraintType) {
|
||||
return constraint;
|
||||
}
|
||||
return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getBaseConstraintOfType(type: Type): Type | undefined {
|
||||
const constraint = getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type);
|
||||
if (!constraint && type.flags & TypeFlags.Index) {
|
||||
return keyofConstraintType;
|
||||
}
|
||||
return constraint;
|
||||
return type.flags & TypeFlags.Index ? keyofConstraintType : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6971,30 +6956,26 @@ namespace ts {
|
||||
* circularly references the type variable.
|
||||
*/
|
||||
function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type {
|
||||
let circular: boolean | undefined;
|
||||
if (!type.resolvedBaseConstraint) {
|
||||
const constraint = getBaseConstraint(type);
|
||||
type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type);
|
||||
return type.resolvedBaseConstraint ||
|
||||
(type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type));
|
||||
|
||||
function getImmediateBaseConstraint(t: Type): Type {
|
||||
if (!t.immediateBaseConstraint) {
|
||||
if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
|
||||
return circularConstraintType;
|
||||
}
|
||||
let result = computeBaseConstraint(getSimplifiedType(t));
|
||||
if (!popTypeResolution()) {
|
||||
result = circularConstraintType;
|
||||
}
|
||||
t.immediateBaseConstraint = result || noConstraintType;
|
||||
}
|
||||
return t.immediateBaseConstraint;
|
||||
}
|
||||
return type.resolvedBaseConstraint;
|
||||
|
||||
function getBaseConstraint(t: Type): Type | undefined {
|
||||
if (t.immediateBaseConstraint) {
|
||||
return t.immediateBaseConstraint === noConstraintType ? undefined : t.immediateBaseConstraint;
|
||||
}
|
||||
if (!pushTypeResolution(t, TypeSystemPropertyName.ImmediateBaseConstraint)) {
|
||||
circular = true;
|
||||
t.immediateBaseConstraint = circularConstraintType;
|
||||
return undefined;
|
||||
}
|
||||
const result = computeBaseConstraint(getSimplifiedType(t));
|
||||
if (!popTypeResolution()) {
|
||||
circular = true;
|
||||
t.immediateBaseConstraint = circularConstraintType;
|
||||
return undefined;
|
||||
}
|
||||
t.immediateBaseConstraint = !result ? noConstraintType : result;
|
||||
return result;
|
||||
const c = getImmediateBaseConstraint(t);
|
||||
return c !== noConstraintType && c !== circularConstraintType ? c : undefined;
|
||||
}
|
||||
|
||||
function computeBaseConstraint(t: Type): Type | undefined {
|
||||
@@ -7877,6 +7858,7 @@ namespace ts {
|
||||
return inferences && getIntersectionType(inferences);
|
||||
}
|
||||
|
||||
/** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */
|
||||
function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type | undefined {
|
||||
if (!typeParameter.constraint) {
|
||||
if (typeParameter.target) {
|
||||
@@ -9145,7 +9127,7 @@ namespace ts {
|
||||
return type.simplified = substituteIndexedMappedType(objectType, type);
|
||||
}
|
||||
if (objectType.flags & TypeFlags.TypeParameter) {
|
||||
const constraint = getConstraintFromTypeParameter(objectType as TypeParameter);
|
||||
const constraint = getConstraintOfTypeParameter(objectType as TypeParameter);
|
||||
if (constraint && isGenericMappedType(constraint)) {
|
||||
return type.simplified = substituteIndexedMappedType(constraint, type);
|
||||
}
|
||||
@@ -12092,7 +12074,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isUnconstrainedTypeParameter(type: Type) {
|
||||
return type.flags & TypeFlags.TypeParameter && !getConstraintFromTypeParameter(<TypeParameter>type);
|
||||
return type.flags & TypeFlags.TypeParameter && !getConstraintOfTypeParameter(<TypeParameter>type);
|
||||
}
|
||||
|
||||
function isTypeReferenceWithGenericArguments(type: Type): boolean {
|
||||
@@ -17620,7 +17602,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const thisType = getTypeFromTypeNode(thisParameter.type);
|
||||
enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintFromTypeParameter(<TypeParameter>thisType) : thisType) as InterfaceType;
|
||||
enclosingClass = ((thisType.flags & TypeFlags.TypeParameter) ? getConstraintOfTypeParameter(<TypeParameter>thisType) : thisType) as InterfaceType;
|
||||
}
|
||||
// No further restrictions for static properties
|
||||
if (flags & ModifierFlags.Static) {
|
||||
@@ -19261,7 +19243,7 @@ namespace ts {
|
||||
typeArguments.pop();
|
||||
}
|
||||
while (typeArguments.length < typeParameters.length) {
|
||||
typeArguments.push(getConstraintFromTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node)));
|
||||
typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isInJavaScriptFile(node)));
|
||||
}
|
||||
const instantiated = createSignatureInstantiation(candidate, typeArguments);
|
||||
candidates[bestIndex] = instantiated;
|
||||
@@ -25164,7 +25146,7 @@ namespace ts {
|
||||
// If the type parameter node does not have an identical constraint as the resolved
|
||||
// type parameter at this position, we report an error.
|
||||
const sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint);
|
||||
const targetConstraint = getConstraintFromTypeParameter(target);
|
||||
const targetConstraint = getConstraintOfTypeParameter(target);
|
||||
if (sourceConstraint) {
|
||||
// relax check if later interface augmentation has no constraint
|
||||
if (!targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ts {
|
||||
getTypeOfSymbol: (sym: Symbol) => Type,
|
||||
getResolvedSymbol: (node: Node) => Symbol,
|
||||
getIndexTypeOfStructuredType: (type: Type, kind: IndexKind) => Type | undefined,
|
||||
getConstraintFromTypeParameter: (typeParameter: TypeParameter) => Type | undefined,
|
||||
getConstraintOfTypeParameter: (typeParameter: TypeParameter) => Type | undefined,
|
||||
getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier) {
|
||||
|
||||
return getSymbolWalker;
|
||||
@@ -93,7 +93,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitTypeParameter(type: TypeParameter): void {
|
||||
visitType(getConstraintFromTypeParameter(type));
|
||||
visitType(getConstraintOfTypeParameter(type));
|
||||
}
|
||||
|
||||
function visitUnionOrIntersectionType(type: UnionOrIntersectionType): void {
|
||||
|
||||
@@ -86,7 +86,7 @@ interface Foo {
|
||||
}
|
||||
|
||||
function foo<T extends Foo | T["hello"]>() {
|
||||
>foo : <T extends Foo | T["hello"]>() => void
|
||||
>foo : <T>() => void
|
||||
>T : T
|
||||
>Foo : Foo
|
||||
>T : T
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
=== tests/cases/compiler/incorrectRecursiveMappedTypeConstraint.ts ===
|
||||
// #17847
|
||||
function sum<T extends { [P in T]: number }, K extends keyof T>(n: number, v: T, k: K) {
|
||||
>sum : <T extends { [x: string]: number; }, K extends keyof T>(n: number, v: T, k: K) => void
|
||||
>sum : <T, K extends keyof T>(n: number, v: T, k: K) => void
|
||||
>T : T
|
||||
>P : P
|
||||
>T : T
|
||||
|
||||
@@ -24,18 +24,18 @@ interface I2<T, U extends U> { }
|
||||
>U : U
|
||||
|
||||
function f<T extends T>() { }
|
||||
>f : <T extends T>() => void
|
||||
>f : <T>() => void
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
function f2<T, U extends U>() { }
|
||||
>f2 : <T, U extends U>() => void
|
||||
>f2 : <T, U>() => void
|
||||
>T : T
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
var a: {
|
||||
>a : { <T extends T>(): void; <T, U extends U>(): void; }
|
||||
>a : { <T>(): void; <T, U>(): void; }
|
||||
|
||||
<T extends T>(): void;
|
||||
>T : T
|
||||
@@ -48,14 +48,14 @@ var a: {
|
||||
}
|
||||
|
||||
var b = <T extends T>() => { }
|
||||
>b : <T extends T>() => void
|
||||
><T extends T>() => { } : <T extends T>() => void
|
||||
>b : <T>() => void
|
||||
><T extends T>() => { } : <T>() => void
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
var b2 = <T, U extends U>() => { }
|
||||
>b2 : <T, U extends U>() => void
|
||||
><T, U extends U>() => { } : <T, U extends U>() => void
|
||||
>b2 : <T, U>() => void
|
||||
><T, U extends U>() => { } : <T, U>() => void
|
||||
>T : T
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
=== tests/cases/compiler/typeParameterHasSelfAsConstraint.ts ===
|
||||
function foo<T extends T>(x: T): number {
|
||||
>foo : <T extends T>(x: T) => number
|
||||
>foo : <T>(x: T) => number
|
||||
>T : T
|
||||
>T : T
|
||||
>x : T
|
||||
|
||||
@@ -23,9 +23,9 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterInd
|
||||
tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(16,21): error TS2313: Type parameter 'T' has a circular constraint.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(16,34): error TS2313: Type parameter 'U' has a circular constraint.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(16,47): error TS2313: Type parameter 'V' has a circular constraint.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,19): error TS2313: Type parameter 'U' has a circular constraint.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,32): error TS2313: Type parameter 'T' has a circular constraint.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(18,45): error TS2313: Type parameter 'V' has a circular constraint.
|
||||
tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts(23,24): error TS2313: Type parameter 'S' has a circular constraint.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterIndirectlyConstrainedToItself.ts (28 errors) ====
|
||||
@@ -97,9 +97,15 @@ tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterInd
|
||||
!!! error TS2313: Type parameter 'V' has a circular constraint.
|
||||
|
||||
class D<U extends T, T extends V, V extends T> { }
|
||||
~
|
||||
!!! error TS2313: Type parameter 'U' has a circular constraint.
|
||||
~
|
||||
!!! error TS2313: Type parameter 'T' has a circular constraint.
|
||||
~
|
||||
!!! error TS2313: Type parameter 'V' has a circular constraint.
|
||||
!!! error TS2313: Type parameter 'V' has a circular constraint.
|
||||
|
||||
// Repro from #25740
|
||||
|
||||
type Foo<T> = [T] extends [number] ? {} : {};
|
||||
function foo<S extends Foo<S>>() {}
|
||||
~~~~~~
|
||||
!!! error TS2313: Type parameter 'S' has a circular constraint.
|
||||
|
||||
@@ -16,7 +16,13 @@ var a: {
|
||||
var b = <U extends T, T extends U>() => { }
|
||||
var b2 = <T extends U, U extends V, V extends T>() => { }
|
||||
|
||||
class D<U extends T, T extends V, V extends T> { }
|
||||
class D<U extends T, T extends V, V extends T> { }
|
||||
|
||||
// Repro from #25740
|
||||
|
||||
type Foo<T> = [T] extends [number] ? {} : {};
|
||||
function foo<S extends Foo<S>>() {}
|
||||
|
||||
|
||||
//// [typeParameterIndirectlyConstrainedToItself.js]
|
||||
var C = /** @class */ (function () {
|
||||
@@ -39,3 +45,4 @@ var D = /** @class */ (function () {
|
||||
}
|
||||
return D;
|
||||
}());
|
||||
function foo() { }
|
||||
|
||||
@@ -90,3 +90,16 @@ class D<U extends T, T extends V, V extends T> { }
|
||||
>V : Symbol(V, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 33))
|
||||
>T : Symbol(T, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 20))
|
||||
|
||||
// Repro from #25740
|
||||
|
||||
type Foo<T> = [T] extends [number] ? {} : {};
|
||||
>Foo : Symbol(Foo, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 50))
|
||||
>T : Symbol(T, Decl(typeParameterIndirectlyConstrainedToItself.ts, 21, 9))
|
||||
>T : Symbol(T, Decl(typeParameterIndirectlyConstrainedToItself.ts, 21, 9))
|
||||
|
||||
function foo<S extends Foo<S>>() {}
|
||||
>foo : Symbol(foo, Decl(typeParameterIndirectlyConstrainedToItself.ts, 21, 45))
|
||||
>S : Symbol(S, Decl(typeParameterIndirectlyConstrainedToItself.ts, 22, 13))
|
||||
>Foo : Symbol(Foo, Decl(typeParameterIndirectlyConstrainedToItself.ts, 17, 50))
|
||||
>S : Symbol(S, Decl(typeParameterIndirectlyConstrainedToItself.ts, 22, 13))
|
||||
|
||||
|
||||
@@ -32,14 +32,14 @@ interface I2<T extends U, U extends V, V extends T> { }
|
||||
>T : T
|
||||
|
||||
function f<U extends T, T extends U>() { }
|
||||
>f : <U extends T, T extends U>() => void
|
||||
>f : <U, T>() => void
|
||||
>U : U
|
||||
>T : T
|
||||
>T : T
|
||||
>U : U
|
||||
|
||||
function f2<T extends U, U extends V, V extends T>() { }
|
||||
>f2 : <T extends U, U extends V, V extends T>() => void
|
||||
>f2 : <T, U, V>() => void
|
||||
>T : T
|
||||
>U : U
|
||||
>U : U
|
||||
@@ -48,7 +48,7 @@ function f2<T extends U, U extends V, V extends T>() { }
|
||||
>T : T
|
||||
|
||||
var a: {
|
||||
>a : { <U extends T, T extends U>(): void; <T extends U, U extends V, V extends T>(): void; }
|
||||
>a : { <U, T>(): void; <T, U, V>(): void; }
|
||||
|
||||
<U extends T, T extends U>(): void;
|
||||
>U : U
|
||||
@@ -66,16 +66,16 @@ var a: {
|
||||
}
|
||||
|
||||
var b = <U extends T, T extends U>() => { }
|
||||
>b : <U extends T, T extends U>() => void
|
||||
><U extends T, T extends U>() => { } : <U extends T, T extends U>() => void
|
||||
>b : <U, T>() => void
|
||||
><U extends T, T extends U>() => { } : <U, T>() => void
|
||||
>U : U
|
||||
>T : T
|
||||
>T : T
|
||||
>U : U
|
||||
|
||||
var b2 = <T extends U, U extends V, V extends T>() => { }
|
||||
>b2 : <T extends U, U extends V, V extends T>() => void
|
||||
><T extends U, U extends V, V extends T>() => { } : <T extends U, U extends V, V extends T>() => void
|
||||
>b2 : <T, U, V>() => void
|
||||
><T extends U, U extends V, V extends T>() => { } : <T, U, V>() => void
|
||||
>T : T
|
||||
>U : U
|
||||
>U : U
|
||||
@@ -92,3 +92,16 @@ class D<U extends T, T extends V, V extends T> { }
|
||||
>V : V
|
||||
>T : T
|
||||
|
||||
// Repro from #25740
|
||||
|
||||
type Foo<T> = [T] extends [number] ? {} : {};
|
||||
>Foo : Foo<T>
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
function foo<S extends Foo<S>>() {}
|
||||
>foo : <S>() => void
|
||||
>S : S
|
||||
>Foo : Foo<T>
|
||||
>S : S
|
||||
|
||||
|
||||
+6
-1
@@ -15,4 +15,9 @@ var a: {
|
||||
var b = <U extends T, T extends U>() => { }
|
||||
var b2 = <T extends U, U extends V, V extends T>() => { }
|
||||
|
||||
class D<U extends T, T extends V, V extends T> { }
|
||||
class D<U extends T, T extends V, V extends T> { }
|
||||
|
||||
// Repro from #25740
|
||||
|
||||
type Foo<T> = [T] extends [number] ? {} : {};
|
||||
function foo<S extends Foo<S>>() {}
|
||||
|
||||
Reference in New Issue
Block a user