// Code generated by tools/gen-rust-ast; DO NOT EDIT.
#![allow(non_snake_case)]

use std::marker;

use crate::common::*;
use crate::flags_generated::*;

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawIntrinsicType {
    pub base: RawType,
    pub intrinsicName: GoString,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct IntrinsicType<'a> {
    pub(crate) raw: *const RawIntrinsicType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> IntrinsicType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn intrinsic_name(self) -> &'a str {
        unsafe { (*self.raw).intrinsicName.as_str() }
    }
}

impl<'a> FromType<'a> for IntrinsicType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::INTRINSIC)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawLiteralType {
    pub base: RawType,
    pub value: GoIface,
    pub freshType: *const RawType,
    pub regularType: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct LiteralType<'a> {
    pub(crate) raw: *const RawLiteralType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> LiteralType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn value(self) -> GoIface {
        unsafe { (*self.raw).value }
    }

    pub fn fresh_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).freshType })
    }

    pub fn regular_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).regularType })
    }
}

impl<'a> FromType<'a> for LiteralType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::FRESHABLE)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawUniqueESSymbolType {
    pub base: RawType,
    pub name: GoString,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct UniqueESSymbolType<'a> {
    pub(crate) raw: *const RawUniqueESSymbolType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> UniqueESSymbolType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn name(self) -> &'a str {
        unsafe { (*self.raw).name.as_str() }
    }
}

impl<'a> FromType<'a> for UniqueESSymbolType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::UNIQUE_ES_SYMBOL)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawTupleType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
    pub _pad1: [u8; 16],
    pub node: *const RawNode,
    pub resolvedTypeArguments: GoSlice<*const RawType>,
    pub allTypeParameters: GoSlice<*const RawType>,
    pub outerTypeParameterCount: isize,
    pub thisType: *const RawType,
    pub baseTypesResolved: u8,
    pub declaredMembersResolved: u8,
    pub _pad2: [u8; 6],
    pub resolvedBaseConstructorType: *const RawType,
    pub resolvedBaseTypes: GoSlice<*const RawType>,
    pub _pad3: [u8; 8],
    pub declaredCallSignatures: GoSlice<*const RawSignature>,
    pub declaredConstructSignatures: GoSlice<*const RawSignature>,
    pub declaredIndexInfos: GoSlice<*const RawIndexInfo>,
    pub elementInfos: GoSlice<RawTupleElementInfo>,
    pub minLength: isize,
    pub fixedLength: isize,
    pub combinedFlags: ElementFlags,
    pub readonly: u8,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct TupleType<'a> {
    pub(crate) raw: *const RawTupleType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> TupleType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn node(self) -> Option<Node<'a>> {
        node_from_raw(unsafe { (*self.raw).node })
    }

    pub fn resolved_type_arguments(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedTypeArguments })
    }

    pub fn all_type_parameters(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).allTypeParameters })
    }

    pub fn outer_type_parameter_count(self) -> isize {
        unsafe { (*self.raw).outerTypeParameterCount }
    }

    pub fn this_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).thisType })
    }

    pub fn base_types_resolved(self) -> bool {
        unsafe { (*self.raw).baseTypesResolved != 0 }
    }

    pub fn declared_members_resolved(self) -> bool {
        unsafe { (*self.raw).declaredMembersResolved != 0 }
    }

    pub fn resolved_base_constructor_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstructorType })
    }

    pub fn resolved_base_types(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedBaseTypes })
    }

    pub fn declared_call_signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).declaredCallSignatures })
    }

    pub fn declared_construct_signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).declaredConstructSignatures })
    }

    pub fn declared_index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).declaredIndexInfos })
    }

    pub fn element_infos(self) -> GoSlice<RawTupleElementInfo> {
        unsafe { (*self.raw).elementInfos }
    }

    pub fn min_length(self) -> isize {
        unsafe { (*self.raw).minLength }
    }

    pub fn fixed_length(self) -> isize {
        unsafe { (*self.raw).fixedLength }
    }

    pub fn combined_flags(self) -> ElementFlags {
        unsafe { (*self.raw).combinedFlags }
    }

    pub fn readonly(self) -> bool {
        unsafe { (*self.raw).readonly != 0 }
    }
}

impl<'a> FromType<'a> for TupleType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT) && _object_flags.intersects(ObjectFlags::TUPLE)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawInstantiationExpressionType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
    pub _pad1: [u8; 16],
    pub node: *const RawNode,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct InstantiationExpressionType<'a> {
    pub(crate) raw: *const RawInstantiationExpressionType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> InstantiationExpressionType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn node(self) -> Option<Node<'a>> {
        node_from_raw(unsafe { (*self.raw).node })
    }
}

impl<'a> FromType<'a> for InstantiationExpressionType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT)
            && _object_flags.intersects(ObjectFlags::INSTANTIATION_EXPRESSION_TYPE)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawMappedType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
    pub _pad1: [u8; 16],
    pub declaration: *const RawNode,
    pub typeParameter: *const RawType,
    pub constraintType: *const RawType,
    pub nameType: *const RawType,
    pub templateType: *const RawType,
    pub modifiersType: *const RawType,
    pub resolvedApparentType: *const RawType,
    pub containsError: u8,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct MappedType<'a> {
    pub(crate) raw: *const RawMappedType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> MappedType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn declaration(self) -> Option<Node<'a>> {
        node_from_raw(unsafe { (*self.raw).declaration })
    }

    pub fn type_parameter(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).typeParameter })
    }

    pub fn constraint_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).constraintType })
    }

    pub fn name_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).nameType })
    }

    pub fn template_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).templateType })
    }

    pub fn modifiers_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).modifiersType })
    }

    pub fn resolved_apparent_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedApparentType })
    }

    pub fn contains_error(self) -> bool {
        unsafe { (*self.raw).containsError != 0 }
    }
}

impl<'a> FromType<'a> for MappedType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT) && _object_flags.intersects(ObjectFlags::MAPPED)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawReverseMappedType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
    pub _pad1: [u8; 16],
    pub source: *const RawType,
    pub mappedType: *const RawType,
    pub constraintType: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct ReverseMappedType<'a> {
    pub(crate) raw: *const RawReverseMappedType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> ReverseMappedType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn source(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).source })
    }

    pub fn mapped_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).mappedType })
    }

    pub fn constraint_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).constraintType })
    }
}

impl<'a> FromType<'a> for ReverseMappedType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT) && _object_flags.intersects(ObjectFlags::REVERSE_MAPPED)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawEvolvingArrayType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
    pub _pad1: [u8; 16],
    pub elementType: *const RawType,
    pub finalArrayType: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct EvolvingArrayType<'a> {
    pub(crate) raw: *const RawEvolvingArrayType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> EvolvingArrayType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn element_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).elementType })
    }

    pub fn final_array_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).finalArrayType })
    }
}

impl<'a> FromType<'a> for EvolvingArrayType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT) && _object_flags.intersects(ObjectFlags::EVOLVING_ARRAY)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawTypeParameter {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub constraint: *const RawType,
    pub target: *const RawType,
    pub _pad0: [u8; 8],
    pub isThisType: u8,
    pub _pad1: [u8; 7],
    pub resolvedDefaultType: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct TypeParameter<'a> {
    pub(crate) raw: *const RawTypeParameter,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> TypeParameter<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).constraint })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn is_this_type(self) -> bool {
        unsafe { (*self.raw).isThisType != 0 }
    }

    pub fn resolved_default_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedDefaultType })
    }
}

impl<'a> FromType<'a> for TypeParameter<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::TYPE_PARAMETER)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawUnionType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub types: GoSlice<*const RawType>,
    pub _pad1: [u8; 16],
    pub resolvedProperties: GoSlice<*const RawSymbol>,
    pub resolvedReducedType: *const RawType,
    pub regularType: *const RawType,
    pub origin: *const RawType,
    pub keyPropertyName: GoString,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct UnionType<'a> {
    pub(crate) raw: *const RawUnionType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> UnionType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn types(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).types })
    }

    pub fn resolved_properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedProperties })
    }

    pub fn resolved_reduced_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedReducedType })
    }

    pub fn regular_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).regularType })
    }

    pub fn origin(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).origin })
    }

    pub fn key_property_name(self) -> &'a str {
        unsafe { (*self.raw).keyPropertyName.as_str() }
    }
}

impl<'a> FromType<'a> for UnionType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::UNION)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawIntersectionType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub types: GoSlice<*const RawType>,
    pub _pad1: [u8; 16],
    pub resolvedProperties: GoSlice<*const RawSymbol>,
    pub resolvedApparentType: *const RawType,
    pub uniqueLiteralFilledInstantiation: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct IntersectionType<'a> {
    pub(crate) raw: *const RawIntersectionType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> IntersectionType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn types(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).types })
    }

    pub fn resolved_properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedProperties })
    }

    pub fn resolved_apparent_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedApparentType })
    }

    pub fn unique_literal_filled_instantiation(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).uniqueLiteralFilledInstantiation })
    }
}

impl<'a> FromType<'a> for IntersectionType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::INTERSECTION)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawIndexType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub target: *const RawType,
    pub indexFlags: IndexFlags,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct IndexType<'a> {
    pub(crate) raw: *const RawIndexType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> IndexType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn index_flags(self) -> IndexFlags {
        unsafe { (*self.raw).indexFlags }
    }
}

impl<'a> FromType<'a> for IndexType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::INDEX)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawIndexedAccessType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub objectType: *const RawType,
    pub indexType: *const RawType,
    pub accessFlags: AccessFlags,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct IndexedAccessType<'a> {
    pub(crate) raw: *const RawIndexedAccessType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> IndexedAccessType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn object_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectType })
    }

    pub fn index_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).indexType })
    }

    pub fn access_flags(self) -> AccessFlags {
        unsafe { (*self.raw).accessFlags }
    }
}

impl<'a> FromType<'a> for IndexedAccessType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::INDEXED_ACCESS)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawTemplateLiteralType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub texts: GoSlice<GoString>,
    pub types: GoSlice<*const RawType>,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct TemplateLiteralType<'a> {
    pub(crate) raw: *const RawTemplateLiteralType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> TemplateLiteralType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn texts(self) -> GoSlice<GoString> {
        unsafe { (*self.raw).texts }
    }

    pub fn types(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).types })
    }
}

impl<'a> FromType<'a> for TemplateLiteralType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::TEMPLATE_LITERAL)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawStringMappingType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub target: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct StringMappingType<'a> {
    pub(crate) raw: *const RawStringMappingType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> StringMappingType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }
}

impl<'a> FromType<'a> for StringMappingType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::STRING_MAPPING)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawSubstitutionType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub baseType: *const RawType,
    pub constraint: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct SubstitutionType<'a> {
    pub(crate) raw: *const RawSubstitutionType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> SubstitutionType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn base_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).baseType })
    }

    pub fn constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).constraint })
    }
}

impl<'a> FromType<'a> for SubstitutionType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::SUBSTITUTION)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawConditionalType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub root: *const RawConditionalRoot,
    pub checkType: *const RawType,
    pub extendsType: *const RawType,
    pub resolvedTrueType: *const RawType,
    pub resolvedFalseType: *const RawType,
    pub resolvedInferredTrueType: *const RawType,
    pub resolvedDefaultConstraint: *const RawType,
    pub resolvedConstraintOfDistributive: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct ConditionalType<'a> {
    pub(crate) raw: *const RawConditionalType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> ConditionalType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn root(self) -> Option<ConditionalRoot<'a>> {
        conditional_root_from_raw(unsafe { (*self.raw).root })
    }

    pub fn check_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).checkType })
    }

    pub fn extends_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).extendsType })
    }

    pub fn resolved_true_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedTrueType })
    }

    pub fn resolved_false_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedFalseType })
    }

    pub fn resolved_inferred_true_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedInferredTrueType })
    }

    pub fn resolved_default_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedDefaultConstraint })
    }

    pub fn resolved_constraint_of_distributive(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedConstraintOfDistributive })
    }
}

impl<'a> FromType<'a> for ConditionalType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::CONDITIONAL)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawConstrainedType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct ConstrainedType<'a> {
    pub(crate) raw: *const RawConstrainedType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> ConstrainedType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }
}

impl<'a> FromType<'a> for ConstrainedType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::STRUCTURED_OR_INSTANTIABLE)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawStructuredType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct StructuredType<'a> {
    pub(crate) raw: *const RawStructuredType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> StructuredType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }
}

impl<'a> FromType<'a> for StructuredType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::STRUCTURED_TYPE)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawObjectType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct ObjectType<'a> {
    pub(crate) raw: *const RawObjectType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> ObjectType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }
}

impl<'a> FromType<'a> for ObjectType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawTypeReference {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
    pub _pad1: [u8; 16],
    pub node: *const RawNode,
    pub resolvedTypeArguments: GoSlice<*const RawType>,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct TypeReference<'a> {
    pub(crate) raw: *const RawTypeReference,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> TypeReference<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn node(self) -> Option<Node<'a>> {
        node_from_raw(unsafe { (*self.raw).node })
    }

    pub fn resolved_type_arguments(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedTypeArguments })
    }
}

impl<'a> FromType<'a> for TypeReference<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT)
            && _object_flags.intersects(
                ObjectFlags::REFERENCE | ObjectFlags::TUPLE | ObjectFlags::CLASS_OR_INTERFACE,
            )
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawInterfaceType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub target: *const RawType,
    pub _pad1: [u8; 16],
    pub node: *const RawNode,
    pub resolvedTypeArguments: GoSlice<*const RawType>,
    pub allTypeParameters: GoSlice<*const RawType>,
    pub outerTypeParameterCount: isize,
    pub thisType: *const RawType,
    pub baseTypesResolved: u8,
    pub declaredMembersResolved: u8,
    pub _pad2: [u8; 6],
    pub resolvedBaseConstructorType: *const RawType,
    pub resolvedBaseTypes: GoSlice<*const RawType>,
    pub _pad3: [u8; 8],
    pub declaredCallSignatures: GoSlice<*const RawSignature>,
    pub declaredConstructSignatures: GoSlice<*const RawSignature>,
    pub declaredIndexInfos: GoSlice<*const RawIndexInfo>,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct InterfaceType<'a> {
    pub(crate) raw: *const RawInterfaceType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> InterfaceType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn target(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).target })
    }

    pub fn node(self) -> Option<Node<'a>> {
        node_from_raw(unsafe { (*self.raw).node })
    }

    pub fn resolved_type_arguments(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedTypeArguments })
    }

    pub fn all_type_parameters(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).allTypeParameters })
    }

    pub fn outer_type_parameter_count(self) -> isize {
        unsafe { (*self.raw).outerTypeParameterCount }
    }

    pub fn this_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).thisType })
    }

    pub fn base_types_resolved(self) -> bool {
        unsafe { (*self.raw).baseTypesResolved != 0 }
    }

    pub fn declared_members_resolved(self) -> bool {
        unsafe { (*self.raw).declaredMembersResolved != 0 }
    }

    pub fn resolved_base_constructor_type(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstructorType })
    }

    pub fn resolved_base_types(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedBaseTypes })
    }

    pub fn declared_call_signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).declaredCallSignatures })
    }

    pub fn declared_construct_signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).declaredConstructSignatures })
    }

    pub fn declared_index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).declaredIndexInfos })
    }
}

impl<'a> FromType<'a> for InterfaceType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::OBJECT)
            && _object_flags.intersects(ObjectFlags::CLASS_OR_INTERFACE | ObjectFlags::TUPLE)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct RawUnionOrIntersectionType {
    pub base: RawType,
    pub resolvedBaseConstraint: *const RawType,
    pub _pad0: [u8; 8],
    pub properties: GoSlice<*const RawSymbol>,
    pub signatures: GoSlice<*const RawSignature>,
    pub callSignatureCount: isize,
    pub indexInfos: GoSlice<*const RawIndexInfo>,
    pub objectTypeWithoutAbstractConstructSignatures: *const RawType,
    pub types: GoSlice<*const RawType>,
    pub _pad1: [u8; 16],
    pub resolvedProperties: GoSlice<*const RawSymbol>,
}

#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct UnionOrIntersectionType<'a> {
    pub(crate) raw: *const RawUnionOrIntersectionType,
    _marker: marker::PhantomData<&'a ()>,
}

impl<'a> UnionOrIntersectionType<'a> {
    #[inline(always)]
    pub fn as_type(self) -> Type<'a> {
        Type::from_raw(self.raw.cast())
    }

    pub fn resolved_base_constraint(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).resolvedBaseConstraint })
    }

    pub fn properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).properties })
    }

    pub fn signatures(self) -> SliceIter<'a, RawSignature, Signature<'a>> {
        slice_iter(unsafe { (*self.raw).signatures })
    }

    pub fn call_signature_count(self) -> isize {
        unsafe { (*self.raw).callSignatureCount }
    }

    pub fn index_infos(self) -> SliceIter<'a, RawIndexInfo, IndexInfo<'a>> {
        slice_iter(unsafe { (*self.raw).indexInfos })
    }

    pub fn object_type_without_abstract_construct_signatures(self) -> Option<Type<'a>> {
        type_from_raw(unsafe { (*self.raw).objectTypeWithoutAbstractConstructSignatures })
    }

    pub fn types(self) -> SliceIter<'a, RawType, Type<'a>> {
        slice_iter(unsafe { (*self.raw).types })
    }

    pub fn resolved_properties(self) -> SliceIter<'a, RawSymbol, Symbol<'a>> {
        slice_iter(unsafe { (*self.raw).resolvedProperties })
    }
}

impl<'a> FromType<'a> for UnionOrIntersectionType<'a> {
    #[inline(always)]
    fn matches(flags: TypeFlags, _object_flags: ObjectFlags) -> bool {
        flags.intersects(TypeFlags::UNION_OR_INTERSECTION)
    }

    #[inline(always)]
    unsafe fn from_type_unchecked(t: Type<'a>) -> Self {
        Self {
            raw: t.raw.cast(),
            _marker: marker::PhantomData,
        }
    }
}
