[analyzer] Use TypeImpl for type annotation types.

The types of `TypeAnnotationImpl.type`, and the fields that override
it, are changed from `DartType?` to `TypeImpl?`. Also, the type of
`TypeAnnotationExtension.typeOrThrow` is changed from `DartType` to
`TypeImpl`.

To reduce the number of casts that need to be added, the following
changes are made in parallel:

- An additional extension `TypeAnnotationImplExtension.typeOrThrow` is
  added; this has the same behavior as
  `TypeAnnotationExtension.typeOrThrow`, but it doesn't require a type
  cast.

- Some field types, getter types, method return types, and method
  parameter types are changed to `Impl` types in the following
  classes:
  - `AstRewriter`
  - `EraseNonJSInteropTypes`
  - `ExtensionTypeErasure`
  - `FreshTypeParameters`
  - `FullInvocationInferrer`
  - `FunctionExpressionInvocationResolver`
  - `FunctionReferenceResolver`
  - `FunctionTypeBuilder`
  - `InstanceCreationInferrer`
  - `InvocationExpressionInferrer`
  - `InvocationInferrer`
  - `NamedTypeBuilder`
  - `NamedTypeResolver`
  - `ResolutionReader`
  - `TypeAliasElementImpl`
  - `TypeAliasElementImpl2`
  - `TypeImpl`
  - `TypeParameterElementImpl`
  - `TypeSystemImpl`

There is no change to the analyzer public API.

This is part of a larger arc of work to change the analyzer's use of
the shared code so that the type parameters it supplies are not part
of the analyzer public API. See
https://github.com/dart-lang/sdk/issues/59763.

Change-Id: I7f753508b53f6744677fd18f66858d70eb974093
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405221
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
index 4174415..40d5369 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/create_getter.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:meta/meta.dart';
@@ -67,7 +68,7 @@
     }
 
     var matchedType = objectPattern.type.typeOrThrow;
-    if (matchedType is! InterfaceType) {
+    if (matchedType is! InterfaceTypeImpl) {
       return;
     }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart b/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart
index 821cb9d..ac716f1 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/move_type_arguments_to_class.dart
@@ -5,8 +5,8 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -41,7 +41,7 @@
     }
 
     var type = namedType.typeOrThrow;
-    if (type is InterfaceType) {
+    if (type is InterfaceTypeImpl) {
       var element = type.element3;
       if (element.typeParameters2.length == typeArguments.arguments.length) {
         await builder.addDartFileEdit(file, (builder) {
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 61c4346..1e5af8b 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -9022,7 +9022,7 @@
   final Token? question;
 
   @override
-  DartType? type;
+  TypeImpl? type;
 
   /// The element associated with the function type, or `null` if the AST
   /// structure hasn't been resolved.
@@ -12546,7 +12546,7 @@
   final Token? question;
 
   @override
-  DartType? type;
+  TypeImpl? type;
 
   /// Initializes a newly created type name.
   ///
@@ -14860,7 +14860,7 @@
   final Token? question;
 
   @override
-  DartType? type;
+  TypeImpl? type;
 
   RecordTypeAnnotationImpl({
     required this.leftParenthesis,
@@ -17834,7 +17834,10 @@
   DartType? get type;
 }
 
-sealed class TypeAnnotationImpl extends AstNodeImpl implements TypeAnnotation {}
+sealed class TypeAnnotationImpl extends AstNodeImpl implements TypeAnnotation {
+  @override
+  TypeImpl? get type;
+}
 
 /// A list of type arguments.
 ///
diff --git a/pkg/analyzer/lib/src/dart/ast/extensions.dart b/pkg/analyzer/lib/src/dart/ast/extensions.dart
index 254d8aa..b40317e 100644
--- a/pkg/analyzer/lib/src/dart/ast/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/ast/extensions.dart
@@ -376,7 +376,16 @@
   /// This accessor should be used on expressions that are expected to
   /// be already resolved. Every such expression must have the type set,
   /// at least `dynamic`.
-  DartType get typeOrThrow {
+  TypeImpl get typeOrThrow => (this as TypeAnnotationImpl).typeOrThrow;
+}
+
+extension TypeAnnotationImplExtension on TypeAnnotationImpl {
+  /// Return the static type of this type annotation.
+  ///
+  /// This accessor should be used on expressions that are expected to
+  /// be already resolved. Every such expression must have the type set,
+  /// at least `dynamic`.
+  TypeImpl get typeOrThrow {
     var type = this.type;
     if (type == null) {
       throw StateError('No type: $this');
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 6569a0b..edc8c24 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -10859,7 +10859,7 @@
   ElementLinkedData? linkedData;
 
   ElementImpl? _aliasedElement;
-  DartType? _aliasedType;
+  TypeImpl? _aliasedType;
 
   @override
   late TypeAliasElementImpl2 element;
@@ -10878,13 +10878,15 @@
   }
 
   @override
-  DartType get aliasedType {
+  TypeImpl get aliasedType {
     linkedData?.read(this);
     return _aliasedType!;
   }
 
   set aliasedType(DartType rawType) {
-    _aliasedType = rawType;
+    // TODO(paulberry): eliminate this cast by changing the type of the
+    // `rawType` parameter.
+    _aliasedType = rawType as TypeImpl;
   }
 
   /// The aliased type, might be `null` if not yet linked.
@@ -10910,7 +10912,7 @@
   /// the constructor-tearoffs specification.
   bool get isProperRename {
     var aliasedType_ = aliasedType;
-    if (aliasedType_ is! InterfaceType) {
+    if (aliasedType_ is! InterfaceTypeImpl) {
       return false;
     }
     var aliasedClass = aliasedType_.element;
@@ -11157,7 +11159,7 @@
   }
 
   @override
-  DartType instantiate(
+  TypeImpl instantiate(
           {required List<DartType> typeArguments,
           required NullabilitySuffix nullabilitySuffix}) =>
       firstFragment.instantiate(
@@ -11347,7 +11349,7 @@
   }
 
   @override
-  TypeParameterType instantiate({
+  TypeParameterTypeImpl instantiate({
     required NullabilitySuffix nullabilitySuffix,
   }) {
     return TypeParameterTypeImpl(
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 74ca4f0..deb653b 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1536,7 +1536,7 @@
   const TypeImpl({this.alias});
 
   @override
-  DartType get extensionTypeErasure {
+  TypeImpl get extensionTypeErasure {
     return const ExtensionTypeErasure().perform(this);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
index 66a9745..2fecad3 100644
--- a/pkg/analyzer/lib/src/dart/element/type_algebra.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -168,7 +168,7 @@
 
   FreshTypeParameters(this.freshTypeParameters, this.substitution);
 
-  FunctionType applyToFunctionType(FunctionType type) {
+  FunctionTypeImpl applyToFunctionType(FunctionType type) {
     return FunctionTypeImpl(
       typeFormals: freshTypeParameters.map((e) => e.firstFragment).toList(),
       parameters: type.parameters.map((parameter) {
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index 4cc0dbe..46de540 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -45,8 +45,10 @@
 class ExtensionTypeErasure extends ReplacementVisitor {
   const ExtensionTypeErasure();
 
-  DartType perform(DartType type) {
-    return type.accept(this) ?? type;
+  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;
   }
 
   @override
@@ -700,8 +702,8 @@
   }
 
   @override
-  InterfaceType instantiateInterfaceToBounds({
-    required InterfaceElement element,
+  InterfaceTypeImpl instantiateInterfaceToBounds({
+    required covariant InterfaceElementImpl element,
     required NullabilitySuffix nullabilitySuffix,
   }) {
     var typeParameters = element.typeParameters;
@@ -746,8 +748,8 @@
   }
 
   @override
-  DartType instantiateTypeAliasToBounds({
-    required TypeAliasElement element,
+  TypeImpl instantiateTypeAliasToBounds({
+    required covariant TypeAliasElementImpl element,
     required NullabilitySuffix nullabilitySuffix,
   }) {
     var typeParameters = element.typeParameters;
diff --git a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
index 9a94441..8d7e283 100644
--- a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_constraint_gatherer.dart';
 import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
@@ -139,7 +140,10 @@
             contextType: UnknownInferredType.instance,
             whyNotPromotedArguments: whyNotPromotedArguments,
             constructorName: constructorName)
-        .resolveInvocation(rawType: constructorRawType);
+        .resolveInvocation(
+            // TODO(paulberry): eliminate this cast by changing the type of
+            // `ConstructorElementToInfer.asType`.
+            rawType: constructorRawType as FunctionTypeImpl);
   }
 
   void _extensionGetter(
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index aee96f7..efc51f3 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/error/codes.dart';
 
 /// Handles possible rewrites of AST.
@@ -54,7 +55,7 @@
           node: node,
           function: SimpleIdentifierImpl(typeNode.name2),
         );
-      } else if (element is TypeAliasElement &&
+      } else if (element is TypeAliasElementImpl &&
           element.aliasedElement is GenericFunctionTypeElement) {
         return _toMethodInvocationOfAliasedTypeLiteral(
           node: node,
@@ -77,7 +78,7 @@
               identifier: SimpleIdentifierImpl(typeNode.name2),
             ),
           );
-        } else if (element is TypeAliasElement &&
+        } else if (element is TypeAliasElementImpl &&
             element.aliasedElement is GenericFunctionTypeElement) {
           return _toMethodInvocationOfAliasedTypeLiteral(
             node: node,
@@ -635,7 +636,7 @@
   MethodInvocation _toMethodInvocationOfAliasedTypeLiteral({
     required InstanceCreationExpressionImpl node,
     required Identifier function,
-    required TypeAliasElement element,
+    required TypeAliasElementImpl element,
   }) {
     var typeName = NamedTypeImpl(
       importPrefix: node.constructorName.type.importPrefix,
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
index 0d7c2d6..568b3c7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_invocation_resolver.dart
@@ -152,7 +152,10 @@
       argumentList: node.argumentList,
       whyNotPromotedArguments: whyNotPromotedArguments,
       contextType: contextType,
-    ).resolveInvocation(rawType: rawType);
+    ).resolveInvocation(
+        // TODO(paulberry): eliminate this cast by changing the type of
+        // `rawType`.
+        rawType: rawType as FunctionTypeImpl);
 
     node.recordStaticType(returnType, resolver: _resolver);
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
index 130d91f..a5a53f2 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_reference_resolver.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
@@ -318,7 +319,7 @@
   /// Resolves [node] as a [TypeLiteral] referencing an interface type directly
   /// (not through a type alias).
   void _resolveDirectTypeLiteral(FunctionReferenceImpl node,
-      IdentifierImpl name, InterfaceElement element) {
+      IdentifierImpl name, InterfaceElementImpl element) {
     var typeArguments = _checkTypeArguments(
       // `node.typeArguments`, coming from the parser, is never null.
       node.typeArguments!, name.name, element.typeParameters,
@@ -622,13 +623,13 @@
       if (node.parent is PropertyAccess) {
         _resolveConstructorReference(node);
         return;
-      } else if (element is InterfaceElement) {
+      } else if (element is InterfaceElementImpl) {
         _resolver.analyzeExpression(
             node.function, _resolver.operations.unknownType);
         _resolver.popRewrite();
         _resolveDirectTypeLiteral(node, prefix, element);
         return;
-      } else if (element is TypeAliasElement) {
+      } else if (element is TypeAliasElementImpl) {
         _resolver.analyzeExpression(prefix, _resolver.operations.unknownType);
         _resolver.popRewrite();
         _resolveTypeAlias(node: node, element: element, typeAlias: prefix);
@@ -743,7 +744,7 @@
       // `prefix.C<int>.name` is initially represented as a [PropertyAccess]
       // with a [FunctionReference] target.
       if (node.parent is PropertyAccess) {
-        if (element is TypeAliasElement &&
+        if (element is TypeAliasElementImpl &&
             element.aliasedType is FunctionType) {
           function.staticElement = element;
           _resolveTypeAlias(node: node, element: element, typeAlias: function);
@@ -751,11 +752,11 @@
           _resolveConstructorReference(node);
         }
         return;
-      } else if (element is InterfaceElement) {
+      } else if (element is InterfaceElementImpl) {
         function.staticElement = element;
         _resolveDirectTypeLiteral(node, function, element);
         return;
-      } else if (element is TypeAliasElement) {
+      } else if (element is TypeAliasElementImpl) {
         function.staticElement = element;
         _resolveTypeAlias(node: node, element: element, typeAlias: function);
         return;
@@ -830,7 +831,7 @@
 
   void _resolveTypeAlias({
     required FunctionReferenceImpl node,
-    required TypeAliasElement element,
+    required TypeAliasElementImpl element,
     required IdentifierImpl typeAlias,
   }) {
     var typeArguments = _checkTypeArguments(
@@ -847,7 +848,7 @@
 
   void _resolveTypeLiteral({
     required FunctionReferenceImpl node,
-    required DartType instantiatedType,
+    required TypeImpl instantiatedType,
     required IdentifierImpl name,
   }) {
     // TODO(srawlins): set the static element of [typeName].
diff --git a/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
index b5fa095..1527d9d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/instance_creation_expression_resolver.dart
@@ -67,7 +67,10 @@
             argumentList: node.argumentList,
             contextType: contextType,
             whyNotPromotedArguments: whyNotPromotedArguments)
-        .resolveInvocation(rawType: elementToInfer?.asType);
+        .resolveInvocation(
+            // TODO(paulberry): eliminate this cast by changing the type of
+            // `ConstructorElementToInfer.asType`.
+            rawType: elementToInfer?.asType as FunctionTypeImpl?);
     node.recordStaticType(node.constructorName.type.type!, resolver: _resolver);
     _resolver.checkForArgumentTypesNotAssignableInList(
         node.argumentList, whyNotPromotedArguments);
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index ec08d46..fbea7d8 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -164,7 +164,10 @@
       argumentList: node.argumentList,
       contextType: contextType,
       whyNotPromotedArguments: whyNotPromotedArguments,
-    ).resolveInvocation(rawType: rawType);
+    ).resolveInvocation(
+        // TODO(paulberry): eliminate this cast by changing the type of
+        // `rawType`.
+        rawType: rawType as FunctionTypeImpl);
 
     node.recordStaticType(returnType, resolver: _resolver);
   }
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
index b8c07ed..9967d5d 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inferrer.dart
@@ -156,7 +156,7 @@
       CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD;
 
   @override
-  DartType resolveInvocation({required FunctionType? rawType}) {
+  DartType resolveInvocation({required FunctionTypeImpl? rawType}) {
     var typeArgumentList = _typeArguments;
     var originalType = rawType;
 
@@ -280,7 +280,7 @@
     if (inferrer != null) {
       typeArgumentTypes = inferrer.chooseFinalTypes();
     }
-    FunctionType? invokeType = typeArgumentTypes != null
+    FunctionTypeImpl? invokeType = typeArgumentTypes != null
         ? originalType?.instantiate(typeArgumentTypes)
         : originalType;
 
@@ -333,7 +333,7 @@
   }
 
   List<ParameterElement>? _storeResult(
-      List<DartType>? typeArgumentTypes, FunctionType? invokeType) {
+      List<DartType>? typeArgumentTypes, FunctionTypeImpl? invokeType) {
     return invokeType?.parameters;
   }
 }
@@ -390,7 +390,7 @@
 
   @override
   List<ParameterElement>? _storeResult(
-      List<DartType>? typeArgumentTypes, FunctionType? invokeType) {
+      List<DartType>? typeArgumentTypes, FunctionTypeImpl? invokeType) {
     if (invokeType != null) {
       var constructedType = invokeType.returnType;
       node.constructorName.type.type = constructedType;
@@ -426,7 +426,7 @@
 
   @override
   List<ParameterElement>? _storeResult(
-      List<DartType>? typeArgumentTypes, FunctionType? invokeType) {
+      List<DartType>? typeArgumentTypes, FunctionTypeImpl? invokeType) {
     node.typeArgumentTypes = typeArgumentTypes;
     node.staticInvokeType = invokeType ?? DynamicTypeImpl.instance;
     return super._storeResult(typeArgumentTypes, invokeType);
@@ -461,7 +461,7 @@
   /// Performs type inference on the invocation expression.  [rawType] should be
   /// the type of the function the invocation is resolved to (with type
   /// arguments not applied yet).
-  void resolveInvocation({required FunctionType? rawType}) {
+  void resolveInvocation({required FunctionTypeImpl? rawType}) {
     var deferredFunctionLiterals = _visitArguments(
         parameterMap: _computeParameterMap(rawType?.parameters ?? const []));
     if (deferredFunctionLiterals != null) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 3b6e73b..c22b7a0 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -492,7 +492,10 @@
             argumentList: node.argumentList,
             whyNotPromotedArguments: whyNotPromotedArguments,
             contextType: contextType)
-        .resolveInvocation(rawType: rawType);
+        .resolveInvocation(
+            // TODO(paulberry): eliminate this cast by changing the type of
+            // `rawType`.
+            rawType: rawType as FunctionTypeImpl?);
   }
 
   /// Resolves the method invocation, [node], as an instance invocation on an
diff --git a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
index b7ff26d..ef7c1b2 100644
--- a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
@@ -171,7 +171,7 @@
 
   /// We are resolving the [NamedType] in a redirecting constructor of the
   /// [enclosingClass].
-  InterfaceType _inferRedirectedConstructor(InterfaceElement element,
+  InterfaceTypeImpl _inferRedirectedConstructor(InterfaceElementImpl element,
       {required TypeConstraintGenerationDataForTesting? dataForTesting,
       required AstNodeImpl? nodeForTesting}) {
     if (element == enclosingClass) {
@@ -202,13 +202,13 @@
     }
   }
 
-  DartType _instantiateElement(NamedTypeImpl node, Element element,
+  TypeImpl _instantiateElement(NamedTypeImpl node, Element element,
       {required TypeConstraintGenerationDataForTesting? dataForTesting}) {
     var nullability = _getNullability(node);
 
     var argumentList = node.typeArguments;
     if (argumentList != null) {
-      if (element is InterfaceElement) {
+      if (element is InterfaceElementImpl) {
         var typeArguments = _buildTypeArguments(
           node,
           argumentList,
@@ -218,7 +218,7 @@
           typeArguments: typeArguments,
           nullabilitySuffix: nullability,
         );
-      } else if (element is TypeAliasElement) {
+      } else if (element is TypeAliasElementImpl) {
         var typeArguments = _buildTypeArguments(
           node,
           argumentList,
@@ -238,7 +238,7 @@
       } else if (element is NeverElementImpl) {
         _buildTypeArguments(node, argumentList, 0);
         return _instantiateElementNever(nullability);
-      } else if (element is TypeParameterElement) {
+      } else if (element is TypeParameterElementImpl) {
         _buildTypeArguments(node, argumentList, 0);
         return element.instantiate(
           nullabilitySuffix: nullability,
@@ -249,7 +249,7 @@
       }
     }
 
-    if (element is InterfaceElement) {
+    if (element is InterfaceElementImpl) {
       if (identical(node, withClause_namedType)) {
         for (var mixin in enclosingClass!.mixins) {
           if (mixin.element == element) {
@@ -267,7 +267,7 @@
         element: element,
         nullabilitySuffix: nullability,
       );
-    } else if (element is TypeAliasElement) {
+    } else if (element is TypeAliasElementImpl) {
       var type = typeSystem.instantiateTypeAliasToBounds(
         element: element,
         nullabilitySuffix: nullability,
@@ -280,7 +280,7 @@
       return DynamicTypeImpl.instance;
     } else if (element is NeverElementImpl) {
       return _instantiateElementNever(nullability);
-    } else if (element is TypeParameterElement) {
+    } else if (element is TypeParameterElementImpl) {
       return element.instantiate(
         nullabilitySuffix: nullability,
       );
@@ -290,7 +290,7 @@
     }
   }
 
-  DartType _instantiateElementNever(NullabilitySuffix nullability) {
+  TypeImpl _instantiateElementNever(NullabilitySuffix nullability) {
     return NeverTypeImpl.instance.withNullability(nullability);
   }
 
@@ -387,7 +387,7 @@
   /// but the [type] is nullable (because the question mark was specified,
   /// or the type alias is nullable), report an error, and return the
   /// corresponding non-nullable type.
-  DartType _verifyNullability(NamedType node, DartType type) {
+  TypeImpl _verifyNullability(NamedType node, TypeImpl type) {
     if (identical(node, classHierarchy_namedType)) {
       if (type.nullabilitySuffix == NullabilitySuffix.question) {
         var parent = node.parent;
@@ -412,17 +412,17 @@
             CompileTimeErrorCode.NULLABLE_TYPE_IN_WITH_CLAUSE,
           );
         }
-        return (type as TypeImpl).withNullability(NullabilitySuffix.none);
+        return type.withNullability(NullabilitySuffix.none);
       }
     }
 
     return type;
   }
 
-  DartType _verifyTypeAliasForContext(
+  TypeImpl _verifyTypeAliasForContext(
     NamedType node,
     TypeAliasElement element,
-    DartType type,
+    TypeImpl type,
   ) {
     // If a type alias that expands to a type parameter.
     if (element.aliasedType is TypeParameterType) {
diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
index e210d34..d34c216 100644
--- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
+++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element2.dart';
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
@@ -18,6 +17,7 @@
     show JoinPatternVariableElementImpl2, MetadataImpl;
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/dart/element/member.dart' show ExecutableMember;
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/utilities/extensions/object.dart';
 import 'package:collection/collection.dart';
@@ -162,7 +162,7 @@
   void visitGenericTypeAlias(GenericTypeAlias node) {
     if (!Identifier.isPrivateName(node.name.lexeme)) {
       var type = node.type.type;
-      if (type is InterfaceType) {
+      if (type is InterfaceTypeImpl) {
         for (var constructor in type.constructors2) {
           if (!Identifier.isPrivateName(constructor.name3!)) {
             usedElements.addElement(constructor);
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index d6290c9..da786af 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -150,7 +150,7 @@
     }
     if (type is DynamicType) {
       // Nothing to do.
-    } else if (type is InterfaceType) {
+    } else if (type is InterfaceTypeImpl) {
       // look up ConstructorElement
       ConstructorElement? constructor;
       var name = node.name;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 3164d01..f3d8076 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2063,7 +2063,10 @@
       argumentList: node.arguments,
       contextType: contextType,
       whyNotPromotedArguments: whyNotPromotedArguments,
-    ).resolveInvocation(rawType: rawType);
+    ).resolveInvocation(
+        // TODO(paulberry): eliminate this cast by changing the type of
+        // `rawType`.
+        rawType: rawType as FunctionTypeImpl?);
 
     node.recordStaticType(
         augmentationTarget is ExecutableElementImpl
@@ -3546,7 +3549,10 @@
             argumentList: node.argumentList,
             contextType: UnknownInferredType.instance,
             whyNotPromotedArguments: whyNotPromotedArguments)
-        .resolveInvocation(rawType: node.staticElement?.type);
+        .resolveInvocation(
+            // TODO(paulberry): eliminate this cast by changing the type of
+            // `RedirectingConstructorInvocationImpl.staticElement`.
+            rawType: node.staticElement?.type as FunctionTypeImpl?);
     checkForArgumentTypesNotAssignableInList(
         node.argumentList, whyNotPromotedArguments);
   }
@@ -3683,7 +3689,10 @@
             argumentList: node.argumentList,
             contextType: UnknownInferredType.instance,
             whyNotPromotedArguments: whyNotPromotedArguments)
-        .resolveInvocation(rawType: node.staticElement?.type);
+        .resolveInvocation(
+            // TODO(paulberry): eliminate this cast by changing the type of
+            // `SuperConstructorInvocationImpl.staticElement`.
+            rawType: node.staticElement?.type as FunctionTypeImpl?);
     checkForArgumentTypesNotAssignableInList(
         node.argumentList, whyNotPromotedArguments);
   }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 0e580a0..f5b8d12 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -7,7 +7,6 @@
 import 'package:_fe_analyzer_shared/src/scanner/string_canonicalizer.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -676,7 +675,7 @@
       parameters: formalParameters,
       question: AstBinaryFlags.hasQuestion(flags) ? Tokens.question() : null,
     );
-    var type = _reader.readRequiredType() as FunctionType;
+    var type = _reader.readRequiredType() as FunctionTypeImpl;
     node.type = type;
 
     var element = GenericFunctionTypeElementImpl.forOffset(-1);
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 16eaeeb..b08a3d0 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -2155,7 +2155,7 @@
 
   FunctionType? readOptionalFunctionType() {
     var type = readType();
-    return type is FunctionType ? type : null;
+    return type is FunctionTypeImpl ? type : null;
   }
 
   T? readOptionalObject<T>(T Function(SummaryDataReader reader) read) {
@@ -2188,7 +2188,7 @@
     return _reader.readStringReferenceList();
   }
 
-  DartType? readType() {
+  TypeImpl? readType() {
     var tag = _reader.readByte();
     if (tag == Tag.NullType) {
       return null;
@@ -2209,13 +2209,13 @@
       );
       return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_none) {
-      var element = readElement() as InterfaceElement;
+      var element = readElement() as InterfaceElementImpl;
       var type = element.instantiate(
           typeArguments: const <DartType>[],
           nullabilitySuffix: NullabilitySuffix.none);
       return _readAliasElementArguments(type);
     } else if (tag == Tag.InterfaceType_noTypeArguments_question) {
-      var element = readElement() as InterfaceElement;
+      var element = readElement() as InterfaceElementImpl;
       var type = element.instantiate(
         typeArguments: const <DartType>[],
         nullabilitySuffix: NullabilitySuffix.question,
@@ -2295,14 +2295,14 @@
     }
   }
 
-  DartType _readAliasElementArguments(DartType type) {
+  TypeImpl _readAliasElementArguments(TypeImpl type) {
     var aliasElement = _readRawElement();
     if (aliasElement is TypeAliasElement) {
       var aliasArguments = _readTypeList();
-      if (type is DynamicType) {
+      if (type is DynamicTypeImpl) {
         // TODO(scheglov): add support for `dynamic` aliasing
         return type;
-      } else if (type is FunctionType) {
+      } else if (type is FunctionTypeImpl) {
         return FunctionTypeImpl(
           typeFormals: type.typeFormals,
           parameters: type.parameters,
@@ -2333,7 +2333,7 @@
             typeArguments: aliasArguments,
           ),
         );
-      } else if (type is TypeParameterType) {
+      } else if (type is TypeParameterTypeImpl) {
         return TypeParameterTypeImpl(
           element: type.element,
           nullabilitySuffix: type.nullabilitySuffix,
@@ -2342,7 +2342,7 @@
             typeArguments: aliasArguments,
           ),
         );
-      } else if (type is VoidType) {
+      } else if (type is VoidTypeImpl) {
         // TODO(scheglov): add support for `void` aliasing
         return type;
       } else {
@@ -2419,7 +2419,7 @@
   }
 
   // TODO(scheglov): Optimize for write/read of types without type parameters.
-  FunctionType _readFunctionType() {
+  FunctionTypeImpl _readFunctionType() {
     // TODO(scheglov): reuse for formal parameters
     var typeParameters = _readTypeParameters(null);
     var returnType = readRequiredType();
diff --git a/pkg/analyzer/lib/src/summary2/function_type_builder.dart b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
index 27b292c..5aa072c 100644
--- a/pkg/analyzer/lib/src/summary2/function_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/function_type_builder.dart
@@ -37,7 +37,7 @@
   ///
   /// When [build] is called, the type is built, stored into this field,
   /// and set for the [node].
-  FunctionType? _type;
+  FunctionTypeImpl? _type;
 
   FunctionTypeBuilder(
     this.typeFormals,
@@ -98,7 +98,7 @@
     );
 
     var fresh = getFreshTypeParameters(typeFormals);
-    type = fresh.applyToFunctionType(type) as FunctionTypeImpl;
+    type = fresh.applyToFunctionType(type);
 
     _type = type;
     node?.type = type;
diff --git a/pkg/analyzer/lib/src/summary2/named_type_builder.dart b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
index f02830c..6110ccf 100644
--- a/pkg/analyzer/lib/src/summary2/named_type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/named_type_builder.dart
@@ -46,7 +46,7 @@
   ///
   /// When [build] is called, the type is built, stored into this field,
   /// and set for the [node].
-  DartType? _type;
+  TypeImpl? _type;
 
   NamedTypeBuilder(this.linker, this.typeSystem, this.element, this.arguments,
       this.nullabilitySuffix,
@@ -96,7 +96,7 @@
     }
 
     var element = this.element;
-    if (element is InterfaceElement) {
+    if (element is InterfaceElementImpl) {
       var parameters = element.typeParameters;
       var arguments = _buildArguments(parameters);
       _type = element.instantiate(
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 7bbc6a4..4eeadde 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,9 +85,10 @@
   // 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
@@ -137,7 +138,7 @@
   final _visitedTypes = <DartType>{};
 
   @override
-  DartType perform(DartType type, {bool keepUserInteropTypes = false}) {
+  TypeImpl perform(TypeImpl type, {bool keepUserInteropTypes = false}) {
     _keepUserInteropTypes = keepUserInteropTypes;
     _visitedTypes.clear();
     return super.perform(type);
@@ -296,11 +297,14 @@
   }) {
     LintCode? lintCode;
     (DartType, DartType) eraseTypes(DartType left, DartType right) {
+      // Note: type casts are needed here because `EraseNonJSInteropTypes`
+      // extends the analyzer's private class `ExtensionTypeErasure`, which uses
+      // `TypeImpl` rather than `DartType`.
       DartType erasedLeft = typeSystem.promoteToNonNull(
-        eraseNonJsInteropTypes.perform(left),
+        eraseNonJsInteropTypes.perform(left as TypeImpl),
       );
       DartType erasedRight = typeSystem.promoteToNonNull(
-        eraseNonJsInteropTypes.perform(right),
+        eraseNonJsInteropTypes.perform(right as TypeImpl),
       );
       var leftIsInteropType = _isJsInteropType(
         erasedLeft,