Elements. Use TypeImpl in more places.

Change-Id: Ie48ade90d01eaad80dc1842ca41cc25ca56c56ad
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/411882
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 17d775e..df977d0e 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -518,7 +518,7 @@
   /// equality.
   bool _canBeEqual(DartType constantType, DartType valueType) {
     if (constantType is InterfaceType) {
-      if (valueType is InterfaceType) {
+      if (valueType is InterfaceTypeImpl) {
         if (constantType.isDartCoreInt && valueType.isDartCoreDouble) {
           return true;
         }
diff --git a/pkg/analyzer/lib/src/dart/element/least_greatest_closure.dart b/pkg/analyzer/lib/src/dart/element/least_greatest_closure.dart
index b9419a9..ea5a9b2 100644
--- a/pkg/analyzer/lib/src/dart/element/least_greatest_closure.dart
+++ b/pkg/analyzer/lib/src/dart/element/least_greatest_closure.dart
@@ -11,9 +11,9 @@
 
 class LeastGreatestClosureHelper extends ReplacementVisitor {
   final TypeSystemImpl typeSystem;
-  final DartType topType;
-  final DartType topFunctionType;
-  final DartType bottomType;
+  final TypeImpl topType;
+  final TypeImpl topFunctionType;
+  final TypeImpl bottomType;
   final Set<TypeParameterElementImpl2> eliminationTargets;
 
   late final bool _isLeastClosure;
@@ -27,14 +27,14 @@
     required this.eliminationTargets,
   });
 
-  DartType get _functionReplacement {
+  TypeImpl get _functionReplacement {
     return _isLeastClosure && _isCovariant ||
             (!_isLeastClosure && !_isCovariant)
         ? bottomType
         : topFunctionType;
   }
 
-  DartType get _typeParameterReplacement {
+  TypeImpl get _typeParameterReplacement {
     return _isLeastClosure && _isCovariant ||
             (!_isLeastClosure && !_isCovariant)
         ? bottomType
@@ -47,27 +47,21 @@
   }
 
   /// Returns a supertype of [type] for all values of [eliminationTargets].
-  TypeImpl eliminateToGreatest(DartType type) {
+  TypeImpl eliminateToGreatest(TypeImpl type) {
     _isCovariant = true;
     _isLeastClosure = false;
-    // TODO(paulberry): make this cast unnecessary by changing the type of
-    // `type` and by changing `ReplacementVisitor` to implement
-    // `TypeVisitor<TypeImpl?>`.
-    return (type.accept(this) ?? type) as TypeImpl;
+    return type.accept(this) ?? type;
   }
 
   /// Returns a subtype of [type] for all values of [eliminationTargets].
-  TypeImpl eliminateToLeast(DartType type) {
+  TypeImpl eliminateToLeast(TypeImpl type) {
     _isCovariant = true;
     _isLeastClosure = true;
-    // TODO(paulberry): make this cast unnecessary by changing the type of
-    // `type` and by changing `ReplacementVisitor` to implement
-    // `TypeVisitor<TypeImpl?>`.
-    return (type.accept(this) ?? type) as TypeImpl;
+    return type.accept(this) ?? type;
   }
 
   @override
-  DartType? visitFunctionType(FunctionType node) {
+  TypeImpl? visitFunctionType(FunctionType node) {
     // - if `S` is
     //   `T Function<X0 extends B0, ...., Xk extends Bk>(T0 x0, ...., Tn xn,
     //       [Tn+1 xn+1, ..., Tm xm])`
@@ -87,9 +81,9 @@
   }
 
   @override
-  DartType? visitTypeParameterType(TypeParameterType type) {
+  TypeImpl? visitTypeParameterType(TypeParameterType type) {
     if (eliminationTargets.contains(type.element3)) {
-      var replacement = _typeParameterReplacement as TypeImpl;
+      var replacement = _typeParameterReplacement;
       return replacement.withNullability(
         uniteNullabilities(
           replacement.nullabilitySuffix,
@@ -117,13 +111,13 @@
   }
 
   /// Returns a supertype of [type] for all values of type parameters.
-  DartType eliminateToGreatest(DartType type) {
+  TypeImpl eliminateToGreatest(TypeImpl type) {
     _isCovariant = true;
     return type.accept(this) ?? type;
   }
 
   @override
-  DartType? visitTypeParameterType(TypeParameterType type) {
+  TypeImpl? visitTypeParameterType(TypeParameterType type) {
     var replacement = _isCovariant ? topType : bottomType;
     return replacement.withNullability(
       uniteNullabilities(
diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
index 7cd22a4..3e54b35 100644
--- a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
+++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
@@ -846,7 +846,7 @@
   }
 
   /// Return the promoted or declared bound of the type parameter.
-  DartType _typeParameterBound(TypeParameterTypeImpl type) {
+  TypeImpl _typeParameterBound(TypeParameterTypeImpl type) {
     var bound = type.promotedBound ?? type.element3.bound;
     if (bound != null) {
       return bound;
diff --git a/pkg/analyzer/lib/src/dart/element/normalize.dart b/pkg/analyzer/lib/src/dart/element/normalize.dart
index 9fed417..890efa8 100644
--- a/pkg/analyzer/lib/src/dart/element/normalize.dart
+++ b/pkg/analyzer/lib/src/dart/element/normalize.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/element/element2.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/extensions.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
@@ -24,7 +25,7 @@
 
   NormalizeHelper(this.typeSystem) : typeProvider = typeSystem.typeProvider;
 
-  DartType normalize(DartType T) {
+  TypeImpl normalize(TypeImpl T) {
     return _normalize(T);
   }
 
@@ -32,7 +33,7 @@
   ///   * where R1 = NORM(R)
   ///   * and B1 = NORM(B)
   ///   * and S1 = NORM(S)
-  FunctionTypeImpl _functionType(FunctionType functionType) {
+  FunctionTypeImpl _functionType(FunctionTypeImpl functionType) {
     var fresh = getFreshTypeParameters2(functionType.typeParameters);
     for (var typeParameter in fresh.freshTypeParameters) {
       var bound = typeParameter.firstFragment.bound;
@@ -56,7 +57,7 @@
   }
 
   /// `NORM(FutureOr<T>)`
-  DartType _futureOr(InterfaceType T) {
+  TypeImpl _futureOr(InterfaceTypeImpl T) {
     // * let S be NORM(T)
     var S = _normalize(T.typeArguments[0]);
     var S_nullability = S.nullabilitySuffix;
@@ -96,7 +97,7 @@
     );
   }
 
-  DartType _normalize(DartType T) {
+  TypeImpl _normalize(TypeImpl T) {
     var T_nullability = T.nullabilitySuffix;
 
     // NORM(T) = T if T is primitive
@@ -105,14 +106,14 @@
         identical(T, NeverTypeImpl.instance) ||
         identical(T, VoidTypeImpl.instance) ||
         T_nullability == NullabilitySuffix.none &&
-            T is InterfaceType &&
+            T is InterfaceTypeImpl &&
             T.typeArguments.isEmpty) {
       return T;
     }
 
     // NORM(FutureOr<T>)
     if (T_nullability == NullabilitySuffix.none &&
-        T is InterfaceType &&
+        T is InterfaceTypeImpl &&
         T.isDartAsyncFutureOr) {
       return _futureOr(T);
     }
@@ -131,7 +132,7 @@
     }
 
     // NORM(C<T0, ..., Tn>) = C<R0, ..., Rn> where Ri is NORM(Ti)
-    if (T is InterfaceType) {
+    if (T is InterfaceTypeImpl) {
       return T.element3.instantiate(
         typeArguments: T.typeArguments.map(_normalize).toFixedList(),
         nullabilitySuffix: NullabilitySuffix.none,
@@ -157,13 +158,13 @@
     }
 
     // NORM(R Function<X extends B>(S)) = R1 Function(X extends B1>(S1)
-    return _functionType(T as FunctionType);
+    return _functionType(T as FunctionTypeImpl);
   }
 
   /// NORM(T?)
-  DartType _nullabilityQuestion(DartType T) {
+  TypeImpl _nullabilityQuestion(TypeImpl T) {
     // * let S be NORM(T)
-    var T_none = (T as TypeImpl).withNullability(NullabilitySuffix.none);
+    var T_none = T.withNullability(NullabilitySuffix.none);
     var S = _normalize(T_none);
     var S_nullability = S.nullabilitySuffix;
 
@@ -184,7 +185,7 @@
 
     // * if S is FutureOr<R> and R is nullable then S
     if (S_nullability == NullabilitySuffix.none &&
-        S is InterfaceType &&
+        S is InterfaceTypeImpl &&
         S.isDartAsyncFutureOr) {
       var R = S.typeArguments[0];
       if (typeSystem.isNullable(R)) {
@@ -194,12 +195,12 @@
 
     // * if S is R? then R?
     // * else S?
-    return (S as TypeImpl).withNullability(NullabilitySuffix.question);
+    return S.withNullability(NullabilitySuffix.question);
   }
 
   /// NORM(X & T)
   /// NORM(X extends T)
-  DartType _typeParameterType(TypeParameterTypeImpl T) {
+  TypeImpl _typeParameterType(TypeParameterTypeImpl T) {
     var element = T.element3;
 
     // NORM(X & T)
@@ -235,7 +236,8 @@
 
   /// NORM(X & T)
   /// * let S be NORM(T)
-  DartType _typeParameterType_promoted(TypeParameterElement2 X, DartType S) {
+  TypeImpl _typeParameterType_promoted(
+      TypeParameterElementImpl2 X, DartType S) {
     // * if S is Never then Never
     if (identical(S, NeverTypeImpl.instance)) {
       return NeverTypeImpl.instance;
diff --git a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
index 8d7e789..2198962 100644
--- a/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/element/replacement_visitor.dart
@@ -22,14 +22,14 @@
 /// otherwise returns `null`.
 class ReplacementVisitor
     implements
-        TypeVisitor<DartType?>,
-        InferenceTypeVisitor<DartType?>,
-        LinkingTypeVisitor<DartType?> {
+        TypeVisitor<TypeImpl?>,
+        InferenceTypeVisitor<TypeImpl?>,
+        LinkingTypeVisitor<TypeImpl?> {
   const ReplacementVisitor();
 
   void changeVariance() {}
 
-  DartType? createFunctionType({
+  FunctionTypeImpl? createFunctionType({
     required FunctionType type,
     required InstantiatedTypeAliasElement? newAlias,
     required List<TypeParameterElement2>? newTypeParameters,
@@ -53,7 +53,7 @@
     );
   }
 
-  DartType? createFunctionTypeBuilder({
+  FunctionTypeBuilder? createFunctionTypeBuilder({
     required FunctionTypeBuilder type,
     required List<TypeParameterElementImpl2>? newTypeParameters,
     required List<FormalParameterElementImpl>? newFormalParameters,
@@ -74,7 +74,7 @@
     );
   }
 
-  DartType? createInterfaceType({
+  InterfaceTypeImpl? createInterfaceType({
     required InterfaceTypeImpl type,
     required InstantiatedTypeAliasElement? newAlias,
     required List<DartType>? newTypeArguments,
@@ -112,18 +112,18 @@
     );
   }
 
-  DartType? createNeverType({
-    required NeverType type,
+  NeverTypeImpl? createNeverType({
+    required NeverTypeImpl type,
     required NullabilitySuffix? newNullability,
   }) {
     if (newNullability == null) {
       return null;
     }
 
-    return (type as TypeImpl).withNullability(newNullability);
+    return type.withNullability(newNullability);
   }
 
-  DartType? createPromotedTypeParameterType({
+  TypeParameterTypeImpl? createPromotedTypeParameterType({
     required TypeParameterType type,
     required NullabilitySuffix? newNullability,
     required DartType? newPromotedBound,
@@ -141,7 +141,7 @@
     );
   }
 
-  DartType? createTypeParameterType({
+  TypeParameterTypeImpl? createTypeParameterType({
     required TypeParameterType type,
     required NullabilitySuffix? newNullability,
   }) {
@@ -157,12 +157,12 @@
   }
 
   @override
-  DartType? visitDynamicType(DynamicType type) {
+  TypeImpl? visitDynamicType(DynamicType type) {
     return null;
   }
 
   @override
-  DartType? visitFunctionType(FunctionType node) {
+  TypeImpl? visitFunctionType(FunctionType node) {
     // TODO(scheglov): avoid this cast
     node as FunctionTypeImpl;
     var newNullability = visitNullability(node);
@@ -272,7 +272,7 @@
   }
 
   @override
-  DartType? visitFunctionTypeBuilder(FunctionTypeBuilder node) {
+  TypeImpl? visitFunctionTypeBuilder(FunctionTypeBuilder node) {
     var newNullability = visitNullability(node);
 
     List<TypeParameterElementImpl2>? newTypeParameters;
@@ -321,9 +321,7 @@
       if (substitution != null) {
         result = substitution.substituteType(result ?? type);
       }
-      // TODO(paulberry): eliminate this cast by changing `ReplacementVisitor`
-      // to implement `TypeVisitor<TypeImpl?>`.
-      return result as TypeImpl?;
+      return result;
     }
 
     var newReturnType = visitType(node.returnType);
@@ -361,7 +359,7 @@
   }
 
   @override
-  DartType? visitInterfaceType(covariant InterfaceTypeImpl type) {
+  TypeImpl? visitInterfaceType(covariant InterfaceTypeImpl type) {
     var newNullability = visitNullability(type);
 
     InstantiatedTypeAliasElement? newAlias;
@@ -393,12 +391,12 @@
   }
 
   @override
-  DartType? visitInvalidType(InvalidType type) {
+  TypeImpl? visitInvalidType(InvalidType type) {
     return null;
   }
 
   @override
-  DartType? visitNamedTypeBuilder(NamedTypeBuilder type) {
+  TypeImpl? visitNamedTypeBuilder(NamedTypeBuilder type) {
     var newNullability = visitNullability(type);
 
     var parameters = const <TypeParameterElement2>[];
@@ -418,7 +416,7 @@
   }
 
   @override
-  DartType? visitNeverType(NeverType type) {
+  TypeImpl? visitNeverType(covariant NeverTypeImpl type) {
     var newNullability = visitNullability(type);
 
     return createNeverType(
@@ -436,7 +434,7 @@
   }
 
   @override
-  DartType? visitRecordType(covariant RecordTypeImpl type) {
+  TypeImpl? visitRecordType(covariant RecordTypeImpl type) {
     var newNullability = visitNullability(type);
 
     InstantiatedTypeAliasElement? newAlias;
@@ -497,7 +495,7 @@
   }
 
   @override
-  DartType? visitRecordTypeBuilder(RecordTypeBuilder type) {
+  TypeImpl? visitRecordTypeBuilder(RecordTypeBuilder type) {
     List<DartType>? newFieldTypes;
     var fieldTypes = type.fieldTypes;
     for (var i = 0; i < fieldTypes.length; i++) {
@@ -535,7 +533,7 @@
   }
 
   @override
-  DartType? visitTypeParameterType(TypeParameterType type) {
+  TypeImpl? visitTypeParameterType(TypeParameterType type) {
     // TODO(scheglov): avoid this cast
     type as TypeParameterTypeImpl;
     var newNullability = visitNullability(type);
@@ -557,12 +555,12 @@
   }
 
   @override
-  DartType? visitUnknownInferredType(UnknownInferredType type) {
+  TypeImpl? visitUnknownInferredType(UnknownInferredType type) {
     return null;
   }
 
   @override
-  DartType? visitVoidType(VoidType type) {
+  TypeImpl? visitVoidType(VoidType type) {
     return null;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 772ff89..1c4fbba 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1308,7 +1308,7 @@
   }
 
   @override
-  TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
+  NeverTypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
     switch (nullabilitySuffix) {
       case NullabilitySuffix.question:
         return instanceNullable;
diff --git a/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart b/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart
index 8072b7b..01a229c 100644
--- a/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_schema_elimination.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/replacement_visitor.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_schema.dart';
 
 /// Visitor that computes least and greatest closures of a type schema.
@@ -12,8 +12,8 @@
 /// type, otherwise it returns the result of substituting `_` with [_bottomType]
 /// or [_topType], as appropriate.
 class TypeSchemaEliminationVisitor extends ReplacementVisitor {
-  final DartType _topType;
-  final DartType _bottomType;
+  final TypeImpl _topType;
+  final TypeImpl _bottomType;
 
   bool _isLeastClosure;
 
@@ -29,18 +29,18 @@
   }
 
   @override
-  DartType visitUnknownInferredType(UnknownInferredType type) {
+  TypeImpl visitUnknownInferredType(UnknownInferredType type) {
     return _isLeastClosure ? _bottomType : _topType;
   }
 
   /// Runs an instance of the visitor on the given [schema] and returns the
   /// resulting type.  If the schema contains no instances of `_`, the original
   /// schema object is returned to avoid unnecessary allocation.
-  static DartType run({
-    required DartType topType,
-    required DartType bottomType,
+  static TypeImpl run({
+    required TypeImpl topType,
+    required TypeImpl bottomType,
     required bool isLeastClosure,
-    required DartType schema,
+    required TypeImpl schema,
   }) {
     var visitor = TypeSchemaEliminationVisitor._(
       topType,
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index f8fb856..e40c119 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -43,13 +43,11 @@
   const ExtensionTypeErasure();
 
   TypeImpl perform(TypeImpl type) {
-    // TODO(paulberry): eliminate this cast by changing `ReplacementVisitor` so
-    // that it implements `TypeVisitor<TypeImpl?>`.
-    return (type.accept(this) ?? type) as TypeImpl;
+    return type.accept(this) ?? type;
   }
 
   @override
-  DartType? visitInterfaceType(covariant InterfaceTypeImpl type) {
+  TypeImpl? visitInterfaceType(covariant InterfaceTypeImpl type) {
     if (type.representationType case var representationType?) {
       var erased = representationType.accept(this) ?? representationType;
       erased as TypeImpl;
@@ -593,7 +591,7 @@
   /// https://github.com/dart-lang/language
   /// See `resources/type-system/inference.md`
   TypeImpl greatestClosure(
-    DartType type,
+    TypeImpl type,
     List<TypeParameterElementImpl2> typeParameters,
   ) {
     var typeParameterSet = Set<TypeParameterElementImpl2>.identity();
@@ -622,15 +620,13 @@
   ///
   /// Note that the greatest closure of a type schema is always a supertype of
   /// any type which matches the schema.
-  TypeImpl greatestClosureOfSchema(DartType schema) {
-    // TODO(paulberry): remove this cast by making `ReplacementVisitor`
-    // implement `TypeVisitor<TypeImpl?>`.
+  TypeImpl greatestClosureOfSchema(TypeImpl schema) {
     return TypeSchemaEliminationVisitor.run(
       topType: objectQuestion,
       bottomType: NeverTypeImpl.instance,
       isLeastClosure: false,
       schema: schema,
-    ) as TypeImpl;
+    );
   }
 
   @override
@@ -1382,7 +1378,7 @@
   /// https://github.com/dart-lang/language
   /// See `resources/type-system/inference.md`
   TypeImpl leastClosure(
-    DartType type,
+    TypeImpl type,
     List<TypeParameterElementImpl2> typeParameters,
   ) {
     var typeParameterSet = Set<TypeParameterElementImpl2>.identity();
@@ -1410,15 +1406,13 @@
   ///
   /// Note that the least closure of a type schema is always a subtype of any
   /// type which matches the schema.
-  TypeImpl leastClosureOfSchema(DartType schema) {
-    // TODO(paulberry): remove this cast by making `ReplacementVisitor`
-    // implement `TypeVisitor<TypeImpl?>`.
+  TypeImpl leastClosureOfSchema(TypeImpl schema) {
     return TypeSchemaEliminationVisitor.run(
       topType: objectQuestion,
       bottomType: NeverTypeImpl.instance,
       isLeastClosure: true,
       schema: schema,
-    ) as TypeImpl;
+    );
   }
 
   @override
@@ -1482,9 +1476,8 @@
   /// https://github.com/dart-lang/language
   /// See `resources/type-system/normalization.md`
   TypeImpl normalize(DartType T) {
-    // TODO(paulberry): eliminate this cast by changing the return type of
-    // `NormalizeHelper.normalize`.
-    return NormalizeHelper(this).normalize(T) as TypeImpl;
+    // TODO(scheglov): remove this cast
+    return NormalizeHelper(this).normalize(T as TypeImpl);
   }
 
   /// Returns a non-nullable version of [type].  This is equivalent to the
diff --git a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
index 167c048..6b6be1f 100644
--- a/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/assignment_expression_resolver.dart
@@ -40,7 +40,7 @@
 
   TypeSystemImpl get _typeSystem => _resolver.typeSystem;
 
-  void resolve(AssignmentExpressionImpl node, {required DartType contextType}) {
+  void resolve(AssignmentExpressionImpl node, {required TypeImpl contextType}) {
     var operator = node.operator.type;
     var hasRead = operator != TokenType.EQ;
     var isIfNull = operator == TokenType.QUESTION_QUESTION_EQ;
@@ -265,7 +265,7 @@
   void _resolveTypes(AssignmentExpressionImpl node,
       {required Map<SharedTypeView, NonPromotionReason> Function()?
           whyNotPromoted,
-      required DartType contextType}) {
+      required TypeImpl contextType}) {
     DartType assignedType;
 
     var rightHandSide = node.rightHandSide;
diff --git a/pkg/analyzer/lib/src/generated/exhaustiveness.dart b/pkg/analyzer/lib/src/generated/exhaustiveness.dart
index 130b26f..935a47d 100644
--- a/pkg/analyzer/lib/src/generated/exhaustiveness.dart
+++ b/pkg/analyzer/lib/src/generated/exhaustiveness.dart
@@ -22,6 +22,7 @@
 import 'package:analyzer/src/dart/constant/value.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/replacement_visitor.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:pub_semver/pub_semver.dart';
@@ -772,7 +773,7 @@
   }
 
   @override
-  DartType? visitTypeParameterType(TypeParameterType node) {
+  TypeImpl? visitTypeParameterType(TypeParameterType node) {
     if (_variance == Variance.contravariant) {
       return _replaceTypeParameterTypes(_typeSystem.typeProvider.neverType);
     } else {
@@ -782,7 +783,9 @@
     }
   }
 
-  DartType _replaceTypeParameterTypes(DartType type) {
+  TypeImpl _replaceTypeParameterTypes(DartType type) {
+    // TODO(scheglov): remove this cast
+    type as TypeImpl;
     return type.accept(this) ?? type;
   }
 
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 792093a..dc533eb 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -82,7 +82,7 @@
   }
 
   void visitConditionalExpression(covariant ConditionalExpressionImpl node,
-      {required DartType contextType}) {
+      {required TypeImpl contextType}) {
     // A conditional expression `E` of the form `b ? e1 : e2` with context type
     // `K` is analyzed as follows:
     //
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index fccaf5b..0737f76 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -211,8 +211,8 @@
     var graph = _TypeParametersGraph(elements, bounds);
     var stronglyConnected = computeStrongComponents(graph);
     for (var component in stronglyConnected) {
-      var dynamicSubstitution = <TypeParameterElement2, DartType>{};
-      var nullSubstitution = <TypeParameterElement2, DartType>{};
+      var dynamicSubstitution = <TypeParameterElement2, TypeImpl>{};
+      var nullSubstitution = <TypeParameterElement2, TypeImpl>{};
       for (var i in component) {
         var element = elements[i];
         dynamicSubstitution[element] = dynamicType;
@@ -231,10 +231,11 @@
     }
 
     for (var i = 0; i < length; i++) {
-      var thisSubstitution = <TypeParameterElement2, DartType>{};
-      var nullSubstitution = <TypeParameterElement2, DartType>{};
+      var thisSubstitution = <TypeParameterElement2, TypeImpl>{};
+      var nullSubstitution = <TypeParameterElement2, TypeImpl>{};
       var element = elements[i];
-      thisSubstitution[element] = bounds[i];
+      // TODO(scheglov): remove this cast
+      thisSubstitution[element] = bounds[i] as TypeImpl;
       nullSubstitution[element] = bottomType;
 
       for (var j = 0; j < length; j++) {
@@ -419,13 +420,13 @@
 }
 
 class _UpperLowerReplacementVisitor extends ReplacementVisitor {
-  final Map<TypeParameterElement2, DartType> _upper;
-  final Map<TypeParameterElement2, DartType> _lower;
+  final Map<TypeParameterElement2, TypeImpl> _upper;
+  final Map<TypeParameterElement2, TypeImpl> _lower;
   Variance _variance;
 
   _UpperLowerReplacementVisitor({
-    required Map<TypeParameterElement2, DartType> upper,
-    required Map<TypeParameterElement2, DartType> lower,
+    required Map<TypeParameterElement2, TypeImpl> upper,
+    required Map<TypeParameterElement2, TypeImpl> lower,
     required Variance variance,
   })  : _upper = upper,
         _lower = lower,
@@ -461,7 +462,7 @@
   }
 
   @override
-  DartType? visitTypeParameterType(TypeParameterType type) {
+  TypeImpl? visitTypeParameterType(TypeParameterType type) {
     if (_variance == Variance.contravariant) {
       return _lower[type.element3];
     } else {
diff --git a/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart b/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
index 045a0d4..0609578 100644
--- a/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
+++ b/pkg/analyzer/test/src/dart/element/least_greatest_closure_test.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:test/test.dart';
@@ -20,7 +19,7 @@
 class GreatestClosureTest extends AbstractTypeSystemTest {
   late final TypeParameterElementImpl2 T;
   late final TypeParameterTypeImpl T_none;
-  late final TypeParameterType T_question;
+  late final TypeParameterTypeImpl T_question;
 
   @override
   void setUp() {
@@ -121,7 +120,7 @@
   }
 
   void _check(
-    DartType type, {
+    TypeImpl type, {
     required String greatest,
     required String least,
   }) {
@@ -138,7 +137,7 @@
     );
   }
 
-  void _check1(DartType type, String expected) {
+  void _check1(TypeImpl type, String expected) {
     _check(type, greatest: expected, least: expected);
   }
 }
diff --git a/pkg/linter/lib/src/rules/invalid_runtime_check_with_js_interop_types.dart b/pkg/linter/lib/src/rules/invalid_runtime_check_with_js_interop_types.dart
index 4eeadde..6e3a7e2 100644
--- a/pkg/linter/lib/src/rules/invalid_runtime_check_with_js_interop_types.dart
+++ b/pkg/linter/lib/src/rules/invalid_runtime_check_with_js_interop_types.dart
@@ -85,10 +85,9 @@
   // what we want here.
   if (element.metadata2.hasJS) return true;
   return _sdkWebLibraries.any((uri) => element.isFromLibrary(uri)) ||
-          // While a type test with types from this library is very rare, we should
-          // still ignore it for consistency.
-          element
-          .isFromLibrary(_dartJsUri);
+      // While a type test with types from this library is very rare, we should
+      // still ignore it for consistency.
+      element.isFromLibrary(_dartJsUri);
 }
 
 /// If [type] is a type declared using `@staticInterop` through
@@ -145,7 +144,7 @@
   }
 
   @override
-  DartType? visitInterfaceType(covariant InterfaceTypeImpl type) {
+  TypeImpl? visitInterfaceType(covariant InterfaceTypeImpl type) {
     if (_keepUserInteropTypes
         ? _isJsInteropType(type, _InteropTypeKind.any)
         : _isJsInteropType(type, _InteropTypeKind.dartJsInteropType)) {
@@ -153,14 +152,17 @@
       // order to just compare the interfaces themselves, we use `thisType`.
       return type.element3.thisType;
     } else {
-      return _jsTypeForStaticInterop(type) ?? super.visitInterfaceType(type);
+      // TODO(scheglov): remove this cast
+      var jsType = _jsTypeForStaticInterop(type) as TypeImpl?;
+      return jsType ?? super.visitInterfaceType(type);
     }
   }
 
   @override
-  DartType? visitTypeParameterType(TypeParameterType type) {
+  TypeImpl? visitTypeParameterType(TypeParameterType type) {
     // Visiting the bound may result in a cycle e.g. `class C<T extends C<T>>`.
-    if (!_visitedTypes.add(type)) return type;
+    // TODO(scheglov): remove this cast
+    if (!_visitedTypes.add(type)) return type as TypeParameterTypeImpl;
     // If the bound is a JS interop type, replace it with its `dart:js_interop`
     // equivalent.
     var newBound = type.bound.accept(this);