Lazy member resolution for class and interface types (#64915)

This commit is contained in:
Anders Hejlsberg authored and GitHub committed 2026-10-23 19:35:05 +00:00
1 parent a91e93821f
commit 8d9b6da99e
31 files changed
+1563 -89

No files matched your search

+192 -66
View File
@@ -598,6 +598,7 @@ type Checker struct {
SignatureCount uint32
TotalInstantiationCount uint32
instantiationCount uint32
memberLayoutCount uint32
instantiationStack []*Type
conditionalConstraintDepth uint32
inlineLevel int
@@ -648,6 +649,7 @@ type Checker struct {
reverseMappedCache map[ReverseMappedTypeKey]*Type
reverseHomomorphicMappedCache map[ReverseMappedTypeKey]*Type
iterationTypesCache map[IterationTypesKey]IterationTypes
memberLayoutCache map[CacheHashKey]*MemberLayout
markerTypes collections.Set[*Type]
resolvingExplicitTypeOfSymbol collections.Set[*ast.Symbol]
constructorOrFunctionChecked collections.Set[*ast.Symbol]
@@ -690,6 +692,9 @@ type Checker struct {
outerTypeParameterListArena core.Arena[[]*Type]
valueSymbolExtraArena core.Arena[valueSymbolExtra]
structuredTypeExtraArena core.Arena[structuredTypeExtra]
lazyStateArena core.Arena[LazyState]
memberLayoutArena core.Arena[MemberLayout]
layoutMemberInfos map[string]MemberInfo
freeTypeSets *temporaryTypeSet
freePropertyCounts *temporaryPropertyCounts
mergedSymbols map[*ast.Symbol]*ast.Symbol
@@ -4587,8 +4592,8 @@ func (c *Checker) getTypeWithoutSignatures(t *Type) *Type {
if len(resolved.getSignatures()) != 0 {
result := c.newObjectType(ObjectFlagsAnonymous, t.symbol)
result.objectFlags |= ObjectFlagsMembersResolved
result.AsObjectType().members = resolved.members
result.AsObjectType().properties = resolved.properties
result.AsObjectType().members = resolved.getMembers()
result.AsObjectType().properties = resolved.getProperties()
return result
}
case t.flags&TypeFlagsIntersection != 0:
@@ -10925,7 +10930,7 @@ func (c *Checker) getInstantiationExpressionType(exprType *Type, node *ast.Node)
debug.Assert(t.symbol != nil, "Instantiation expression source type must have a symbol")
symbol.SetDeclarations(t.symbol.Declarations())
result := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsInstantiationExpressionType, symbol)
c.setStructuredTypeMembers(result, resolved.members, callSignatures, constructSignatures, resolved.getIndexInfos())
c.setStructuredTypeMembers(result, resolved.getMembers(), callSignatures, constructSignatures, resolved.getIndexInfos())
result.AsInstantiationExpressionType().node = node
return result
}
@@ -16137,7 +16142,7 @@ func (c *Checker) cloneTypeAsModuleType(symbol *ast.Symbol, moduleType *Type, re
links.target = symbol
links.originatingImport = referenceParent
resolvedModuleType := c.resolveStructuredTypeMembers(moduleType)
c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.members, nil, nil, resolvedModuleType.getIndexInfos())
c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.getMembers(), nil, nil, resolvedModuleType.getIndexInfos())
return result
}
@@ -19289,7 +19294,34 @@ func (c *Checker) getPropertiesOfType(t *Type) []*ast.Symbol {
func (c *Checker) getPropertiesOfObjectType(t *Type) []*ast.Symbol {
if t.flags&TypeFlagsObject != 0 {
return c.resolveStructuredTypeMembers(t).properties
return c.resolveStructuredTypeMembers(t).getProperties()
}
return nil
}
// For classes and interfaces, the layout properties of the type are uninstantiated symbols from
// the shared member layout. When operations only process the declaration, flags, and/or name
// of members (and not their type), using the layout properties helps defer instantiation of
// the members. For example, `keyof T` can be computed entirely from layout properties.
func (c *Checker) getLayoutPropertiesOfType(t *Type) []*ast.Symbol {
t = c.getReducedApparentType(t)
lazy := c.getLazyStateOfType(t)
if lazy == nil {
return c.getPropertiesOfType(t)
}
layout := lazy.layout
if layout.layoutProperties == nil {
layout.layoutProperties = make([]*ast.Symbol, len(layout.memberInfos))
for i, memberInfo := range layout.memberInfos {
layout.layoutProperties[i] = memberInfo.symbol
}
}
return layout.layoutProperties
}
func (c *Checker) getLazyStateOfType(t *Type) *LazyState {
if t.flags&TypeFlagsObject != 0 {
return c.resolveStructuredTypeMembers(t).getLazyState()
}
return nil
}
@@ -19337,7 +19369,7 @@ func (c *Checker) getPropertyOfTypeEx(t *Type, name string, skipObjectFunctionPr
switch {
case t.flags&TypeFlagsObject != 0:
resolved := c.resolveStructuredTypeMembers(t)
symbol := resolved.members[name]
symbol := resolved.getMember(name)
if symbol != nil {
if !includeTypeOnlyMembers && t.symbol != nil && t.symbol.Flags()&ast.SymbolFlagsValueModule != 0 && c.moduleSymbolLinks.Get(t.symbol).typeOnlyExportStarMap[name] != nil {
// If this is the type of a module, `resolved.members.get(name)` might have effectively skipped over
@@ -19503,10 +19535,8 @@ func (c *Checker) resolveStructuredTypeMembers(t *Type) *StructuredType {
switch {
case t.flags&TypeFlagsObject != 0:
switch {
case t.objectFlags&ObjectFlagsReference != 0:
c.resolveTypeReferenceMembers(t)
case t.objectFlags&ObjectFlagsClassOrInterface != 0:
c.resolveClassOrInterfaceMembers(t)
case t.objectFlags&(ObjectFlagsClassOrInterface|ObjectFlagsReference) != 0:
c.resolveObjectTypeMembers(t)
case t.objectFlags&ObjectFlagsReverseMapped != 0:
c.resolveReverseMappedTypeMembers(t)
case t.objectFlags&ObjectFlagsAnonymous != 0:
@@ -19527,68 +19557,164 @@ func (c *Checker) resolveStructuredTypeMembers(t *Type) *StructuredType {
return t.AsStructuredType()
}
func (c *Checker) resolveClassOrInterfaceMembers(t *Type) {
c.resolveObjectTypeMembers(t, t, nil, nil)
}
func (c *Checker) resolveTypeReferenceMembers(t *Type) {
source := t.Target()
typeParameters := source.AsInterfaceType().allTypeParameters
typeArguments := c.getTypeArguments(t)
paddedTypeArguments := typeArguments
if len(typeArguments) == len(typeParameters)-1 {
paddedTypeArguments = core.Concatenate(typeArguments, []*Type{t})
}
c.resolveObjectTypeMembers(t, source, typeParameters, paddedTypeArguments)
}
func (c *Checker) resolveObjectTypeMembers(t *Type, source *Type, typeParameters []*Type, typeArguments []*Type) {
func (c *Checker) resolveObjectTypeMembers(t *Type) {
var mapper *TypeMapper
var typeParameters []*Type
var typeArguments []*Type
var members ast.SymbolTable
var callSignatures []*Signature
var constructSignatures []*Signature
var indexInfos []*IndexInfo
var instantiated bool
source := c.getTargetType(t)
if t.objectFlags&ObjectFlagsReference != 0 {
typeParameters = source.AsInterfaceType().allTypeParameters
typeArguments = c.getTypeArguments(t)
if len(typeArguments) == len(typeParameters)-1 {
typeArguments = core.Concatenate(typeArguments, []*Type{t})
}
}
resolved := c.resolveDeclaredMembers(source)
if slices.Equal(typeParameters, typeArguments) {
members = resolved.declaredMembers
callSignatures = resolved.declaredCallSignatures
constructSignatures = resolved.declaredConstructSignatures
indexInfos = resolved.declaredIndexInfos
} else {
instantiated = true
mapper = newTypeMapper(typeParameters, typeArguments)
members = c.instantiateSymbolTable(resolved.declaredMembers, mapper)
callSignatures = c.instantiateSignatures(resolved.declaredCallSignatures, mapper)
constructSignatures = c.instantiateSignatures(resolved.declaredConstructSignatures, mapper)
indexInfos = c.instantiateIndexInfos(resolved.declaredIndexInfos, mapper)
}
baseTypes := c.getBaseTypes(source)
if len(baseTypes) != 0 {
if !instantiated {
members = maps.Clone(members)
}
thisArgument := core.LastOrNil(typeArguments)
for _, baseType := range baseTypes {
instantiatedBaseType := baseType
if thisArgument != nil {
instantiatedBaseType = c.getTypeWithThisArgument(c.instantiateType(baseType, mapper), thisArgument, false /*needsApparentType*/)
}
members = c.addInheritedMembers(members, c.getPropertiesOfType(instantiatedBaseType))
callSignatures = core.Concatenate(callSignatures, c.getSignaturesOfType(instantiatedBaseType, SignatureKindCall))
constructSignatures = core.Concatenate(constructSignatures, c.getSignaturesOfType(instantiatedBaseType, SignatureKindConstruct))
var inheritedIndexInfos []*IndexInfo
if instantiatedBaseType != c.anyType {
inheritedIndexInfos = c.getIndexInfosOfType(instantiatedBaseType)
} else {
inheritedIndexInfos = []*IndexInfo{c.anyBaseTypeIndexInfo}
}
indexInfos = core.Concatenate(indexInfos, core.Filter(inheritedIndexInfos, func(info *IndexInfo) bool {
return findIndexInfo(indexInfos, info.keyType) == nil
}))
instantiatedBaseTypes := baseTypes
thisArgument := core.LastOrNil(typeArguments)
if len(baseTypes) != 0 && thisArgument != nil {
instantiatedBaseTypes = make([]*Type, len(baseTypes))
for i, baseType := range baseTypes {
instantiatedBaseTypes[i] = c.getTypeWithThisArgument(c.instantiateType(baseType, mapper), thisArgument, false /*needsApparentType*/)
}
}
// Member layout must be computed before inherited signatures, which may circularly depend on it
layout := c.getMemberLayout(t, instantiatedBaseTypes)
for _, instantiatedBaseType := range instantiatedBaseTypes {
callSignatures = core.Concatenate(callSignatures, c.getSignaturesOfType(instantiatedBaseType, SignatureKindCall))
constructSignatures = core.Concatenate(constructSignatures, c.getSignaturesOfType(instantiatedBaseType, SignatureKindConstruct))
var inheritedIndexInfos []*IndexInfo
if instantiatedBaseType != c.anyType {
inheritedIndexInfos = c.getIndexInfosOfType(instantiatedBaseType)
} else {
inheritedIndexInfos = []*IndexInfo{c.anyBaseTypeIndexInfo}
}
indexInfos = core.Concatenate(indexInfos, core.Filter(inheritedIndexInfos, func(info *IndexInfo) bool {
return findIndexInfo(indexInfos, info.keyType) == nil
}))
}
c.setStructuredTypeMembers(t, members, callSignatures, constructSignatures, indexInfos)
lazyState := c.lazyStateArena.New()
lazyState.layout = layout
lazyState.mapper = mapper
lazyState.baseTypes = instantiatedBaseTypes
t.AsTypeReference().lazy = lazyState
}
func (c *Checker) getMemberLayout(t *Type, baseTypes []*Type) *MemberLayout {
if t.objectFlags&ObjectFlagsReference == 0 {
return c.createMemberLayout(t, baseTypes)
}
source := c.getTargetType(t)
key := c.getMemberLayoutKey(source, baseTypes)
layout := c.memberLayoutCache[key]
if layout == nil {
layout = c.createMemberLayout(source, baseTypes)
if c.memberLayoutCache == nil {
c.memberLayoutCache = make(map[CacheHashKey]*MemberLayout)
}
c.memberLayoutCache[key] = layout
}
return layout
}
func (c *Checker) getMemberLayoutKey(t *Type, baseTypes []*Type) CacheHashKey {
var b keyBuilder
b.reserve(20 + 5*len(baseTypes))
b.writeType(t)
// Late binding may add new declared members, so include the declared member count in the key
b.writeInt(len(t.AsInterfaceType().declaredMembers))
b.writeInt(len(baseTypes))
for _, baseType := range baseTypes {
if baseType.objectFlags&ObjectFlagsReference != 0 {
c.resolveStructuredTypeMembers(baseType)
b.writeByte('+')
b.writeUint32(baseType.AsTypeReference().lazy.layout.id)
} else {
b.writeByte('-')
b.writeType(baseType)
}
}
return b.hash()
}
func (c *Checker) createMemberLayout(t *Type, baseTypes []*Type) *MemberLayout {
// Reuse c.layoutMemberInfos to avoid repeated allocations
layoutMemberInfos := c.layoutMemberInfos
c.layoutMemberInfos = nil
addMember := func(symbol *ast.Symbol, baseIndex int) {
if _, ok := layoutMemberInfos[symbol.Name()]; !ok {
if layoutMemberInfos == nil {
layoutMemberInfos = make(map[string]MemberInfo)
}
layoutMemberInfos[symbol.Name()] = MemberInfo{symbol: symbol, baseIndex: int32(baseIndex)}
}
}
// Add declared members
for id, symbol := range t.AsInterfaceType().declaredMembers {
if c.isNamedMember(symbol, id) {
addMember(symbol, -1)
}
}
// Add inherited members
for baseIndex, baseType := range baseTypes {
if baseType.objectFlags&(ObjectFlagsReference|ObjectFlagsClassOrInterface) != 0 {
c.resolveStructuredTypeMembers(baseType)
for _, info := range baseType.AsTypeReference().lazy.layout.memberInfos {
if !isStaticPrivateIdentifierProperty(info.symbol) {
addMember(info.symbol, baseIndex)
}
}
} else {
for _, symbol := range c.getPropertiesOfType(baseType) {
if !isStaticPrivateIdentifierProperty(symbol) {
addMember(symbol, baseIndex)
}
}
}
}
memberInfos := slices.AppendSeq(make([]MemberInfo, 0, len(layoutMemberInfos)), maps.Values(layoutMemberInfos))
clear(layoutMemberInfos)
c.layoutMemberInfos = layoutMemberInfos
// Sort by symbols, but put declared members (baseIndex < 0) first
slices.SortFunc(memberInfos, func(a, b MemberInfo) int {
if a.baseIndex < 0 && b.baseIndex >= 0 {
return -1
}
if a.baseIndex >= 0 && b.baseIndex < 0 {
return 1
}
return c.CompareSymbols(a.symbol, b.symbol)
})
// Store slot indices in the sorted memberInfos and build the memberInfoMap. Slot indices are used to
// identify slots in the instantiated type's properties list.
memberInfoMap := make(map[string]*MemberInfo, len(memberInfos))
for i := range memberInfos {
memberInfo := &memberInfos[i]
memberInfo.slotIndex = int32(i)
memberInfoMap[memberInfo.symbol.Name()] = memberInfo
}
layout := c.memberLayoutArena.New()
layout.id = c.memberLayoutCount
layout.memberInfoMap = memberInfoMap
layout.memberInfos = memberInfos
c.memberLayoutCount++
return layout
}
func findIndexInfo(indexInfos []*IndexInfo, keyType *Type) *IndexInfo {
@@ -19789,7 +19915,7 @@ func (c *Checker) getSingleCallOrConstructSignature(t *Type) *Signature {
func (c *Checker) getSingleSignature(t *Type, kind SignatureKind, allowMembers bool) *Signature {
if t.flags&TypeFlagsObject != 0 {
resolved := c.resolveStructuredTypeMembers(t)
if allowMembers || len(resolved.properties) == 0 && len(resolved.getIndexInfos()) == 0 {
if allowMembers || !resolved.hasProperties() && len(resolved.getIndexInfos()) == 0 {
if kind == SignatureKindCall && len(resolved.CallSignatures()) == 1 && len(resolved.ConstructSignatures()) == 0 {
return resolved.CallSignatures()[0]
}
@@ -21136,7 +21262,7 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) {
if baseConstructorIndexInfo != nil {
indexInfos = append(indexInfos, baseConstructorIndexInfo)
}
if symbol.Flags()&ast.SymbolFlagsEnum != 0 && (c.getDeclaredTypeOfSymbol(symbol).flags&TypeFlagsEnum != 0 || core.Some(d.properties, func(prop *ast.Symbol) bool {
if symbol.Flags()&ast.SymbolFlagsEnum != 0 && (c.getDeclaredTypeOfSymbol(symbol).flags&TypeFlagsEnum != 0 || core.Some(d.getProperties(), func(prop *ast.Symbol) bool {
return c.getTypeOfSymbol(prop).flags&TypeFlagsNumberLike != 0
})) {
indexInfos = append(indexInfos, c.enumNumberIndexInfo)
@@ -21196,11 +21322,11 @@ func (c *Checker) instantiateSymbolTable(symbols ast.SymbolTable, m *TypeMapper)
}
func (c *Checker) instantiateSymbol(symbol *ast.Symbol, m *TypeMapper) *ast.Symbol {
if symbol == nil {
return nil
if symbol == nil || m == nil {
return symbol
}
links := c.valueSymbolLinks.Get(symbol)
if m != nil && m.MapsThisOnly() && isThisless(symbol) {
if m.MapsThisOnly() && isThisless(symbol) {
return symbol
}
// If the type of the symbol is already resolved, and if that type could not possibly
@@ -21844,7 +21970,7 @@ func (c *Checker) includeMixinType(t *Type, types []*Type, mixinFlags []bool, in
func (c *Checker) getPropertyOfObjectType(t *Type, name string) *ast.Symbol {
if t.flags&TypeFlagsObject != 0 {
resolved := c.resolveStructuredTypeMembers(t)
symbol := resolved.members[name]
symbol := resolved.getMember(name)
if symbol != nil && c.symbolIsValue(symbol) {
return symbol
}
@@ -22322,7 +22448,7 @@ func (c *Checker) somePropertyReducesToNever(t *Type) bool {
counts := c.getTemporaryPropertyCounts()
defer c.releaseTemporaryPropertyCounts(counts)
for _, t := range t.Types() {
for _, prop := range c.getPropertiesOfType(t) {
for _, prop := range c.getLayoutPropertiesOfType(t) {
counts.Set(prop.Name(), counts.GetOrZero(prop.Name())+1)
}
}
@@ -27080,7 +27206,7 @@ func (c *Checker) IsEmptyAnonymousObjectType(t *Type) bool {
}
func (c *Checker) isEmptyResolvedType(t *StructuredType) bool {
return t.AsType() != c.anyFunctionType && len(t.properties) == 0 && len(t.getSignatures()) == 0 && len(t.getIndexInfos()) == 0
return t.AsType() != c.anyFunctionType && !t.hasProperties() && len(t.getSignatures()) == 0 && len(t.getIndexInfos()) == 0
}
func (c *Checker) isEmptyObjectType(t *Type) bool {
@@ -27328,7 +27454,7 @@ func (c *Checker) getLiteralTypeFromProperties(t *Type, include TypeFlags, inclu
if includeOrigin && t.objectFlags&(ObjectFlagsClassOrInterface|ObjectFlagsReference) != 0 || t.alias != nil {
origin = c.newIndexType(t, IndexFlagsNone)
}
props := c.getPropertiesOfType(t)
props := c.getLayoutPropertiesOfType(t)
indexInfos := c.getIndexInfosOfType(t)
types := make([]*Type, 0, len(props)+len(indexInfos))
for _, prop := range props {
@@ -27741,7 +27867,7 @@ func (c *Checker) getPropertyTypeForIndexType(originalObjectType *Type, objectTy
c.addDiagnostic(createDiagnosticForNode(accessExpression, diagnostics.Property_0_does_not_exist_on_type_1, indexType.AsLiteralType().value, c.TypeToString(objectType)))
return c.undefinedType
} else if indexType.flags&(TypeFlagsNumber|TypeFlagsString) != 0 {
types := core.Map(objectType.AsStructuredType().properties, func(prop *ast.Symbol) *Type {
types := core.Map(objectType.AsStructuredType().getProperties(), func(prop *ast.Symbol) *Type {
return c.getTypeOfSymbol(prop)
})
return c.getUnionType(append(types, c.undefinedType))
@@ -27968,7 +28094,7 @@ func (c *Checker) getPropertyNameFromIndex(indexType *Type, accessNode *ast.Node
}
func (c *Checker) isStringIndexSignatureOnlyTypeWorker(t *Type) bool {
return t.flags&TypeFlagsObject != 0 && !c.isGenericMappedType(t) && len(c.getPropertiesOfType(t)) == 0 && len(c.getIndexInfosOfType(t)) == 1 && c.getIndexInfoOfType(t, c.stringType) != nil ||
return t.flags&TypeFlagsObject != 0 && !c.isGenericMappedType(t) && len(c.getLayoutPropertiesOfType(t)) == 0 && len(c.getIndexInfosOfType(t)) == 1 && c.getIndexInfoOfType(t, c.stringType) != nil ||
t.flags&TypeFlagsUnionOrIntersection != 0 && core.Every(t.Types(), c.isStringIndexSignatureOnlyType)
}
@@ -31416,7 +31542,7 @@ func (c *Checker) discriminateContextualTypeByObjectMembers(node *ast.Node, cont
}
return false
})
discriminantMembers := core.Filter(c.getPropertiesOfType(contextualType), func(s *ast.Symbol) bool {
discriminantMembers := core.Filter(c.getLayoutPropertiesOfType(contextualType), func(s *ast.Symbol) bool {
return s.Flags()&ast.SymbolFlagsOptional != 0 && node.Symbol().Members()[s.Name()] == nil && c.isDiscriminantProperty(contextualType, s.Name())
})
discriminator := &ObjectLiteralDiscriminator{c: c, props: discriminantProperties, members: discriminantMembers}
@@ -31788,7 +31914,7 @@ func (c *Checker) isFunctionObjectType(t *Type) bool {
// We do a quick check for a "bind" property before performing the more expensive subtype
// check. This gives us a quicker out in the common case where an object type is not a function.
resolved := c.resolveStructuredTypeMembers(t)
return len(resolved.getSignatures()) != 0 || resolved.members["bind"] != nil && c.isTypeSubtypeOf(t, c.globalFunctionType)
return len(resolved.getSignatures()) != 0 || resolved.getMember("bind") != nil && c.isTypeSubtypeOf(t, c.globalFunctionType)
}
func (c *Checker) getTypeWithFacts(t *Type, include TypeFacts) *Type {
@@ -32284,7 +32410,7 @@ func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Sy
// member should more exactly be the kind of (declarationless) symbol we want.
// (See #44364 and #45031 for relevant implementation PRs)
if metaProp.KeywordToken == ast.KindImportKeyword && node.Text() == "meta" {
return c.getGlobalImportMetaExpressionType().AsObjectType().members["meta"]
return c.getGlobalImportMetaExpressionType().AsObjectType().getMember("meta")
}
// no other meta properties are valid syntax, thus no others should have symbols
return nil
+1 -1
View File
@@ -263,7 +263,7 @@ func (b *NodeBuilderImpl) expandInterfaceDecl(symbol *ast.Symbol) *ast.Node {
members = append(members, b.signatureToSignatureDeclarationHelper(sig, ast.KindCallSignature, nil))
}
// Properties, filtering inherited
filteredProps := b.filterInheritedProperties(interfaceType, baseTypes, resolved.properties)
filteredProps := b.filterInheritedProperties(interfaceType, baseTypes, resolved.getProperties())
members = b.serializePropertiesWithTruncation(filteredProps, members)
// Heritage clauses
+5 -5
View File
@@ -576,7 +576,7 @@ func (b *NodeBuilderImpl) getResolvedTypeWithoutAbstractConstructSignatures(t *S
t.extra.objectTypeWithoutAbstractConstructSignatures = t.AsType()
return t.AsType()
}
typeCopy := b.ch.newAnonymousType(t.symbol, t.members, t.CallSignatures(), core.IfElse(len(constructSignatures) > 0, constructSignatures, []*Signature{}), t.getIndexInfos())
typeCopy := b.ch.newAnonymousType(t.symbol, t.getMembers(), t.CallSignatures(), core.IfElse(len(constructSignatures) > 0, constructSignatures, []*Signature{}), t.getIndexInfos())
t.extra.objectTypeWithoutAbstractConstructSignatures = typeCopy
typeCopy.AsStructuredType().ensureExtra().objectTypeWithoutAbstractConstructSignatures = typeCopy
return typeCopy
@@ -2758,7 +2758,7 @@ func (b *NodeBuilderImpl) createTypeNodesFromResolvedType(resolvedType *Structur
typeElements = slices.Concat(typeElements, b.indexInfoToObjectComputedNamesOrSignatureDeclaration(info, typeNode))
}
properties := resolvedType.properties
properties := resolvedType.getProperties()
if len(properties) == 0 {
return b.f.NewNodeList(typeElements)
}
@@ -2807,7 +2807,7 @@ func (b *NodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode {
resolved := b.ch.resolveStructuredTypeMembers(t)
callSigs := resolved.CallSignatures()
ctorSigs := resolved.ConstructSignatures()
if len(resolved.properties) == 0 && len(resolved.getIndexInfos()) == 0 {
if len(resolved.getProperties()) == 0 && len(resolved.getIndexInfos()) == 0 {
if len(callSigs) == 0 && len(ctorSigs) == 0 {
b.ctx.approximateLength += 2
result := b.f.NewTypeLiteralNode(b.f.NewNodeList([]*ast.Node{}))
@@ -2836,9 +2836,9 @@ func (b *NodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode {
return b.ch.getOrCreateTypeFromSignature(s)
})
// count the number of type elements excluding abstract constructors
typeElementCount := len(callSigs) + (len(ctorSigs) - len(abstractSignatures)) + len(resolved.getIndexInfos()) + core.IfElse(b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0, core.CountWhere(resolved.properties, func(p *ast.Symbol) bool {
typeElementCount := len(callSigs) + (len(ctorSigs) - len(abstractSignatures)) + len(resolved.getIndexInfos()) + core.IfElse(b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0, core.CountWhere(resolved.getProperties(), func(p *ast.Symbol) bool {
return p.Flags()&ast.SymbolFlagsPrototype == 0
}), len(resolved.properties))
}), len(resolved.getProperties()))
// don't include an empty object literal if there were no other static-side
// properties to write, i.e. `abstract class C { }` becomes `abstract new () => {}`
// and not `(abstract new () => {}) & {}`
+5 -3
View File
@@ -679,7 +679,7 @@ func (c *Checker) elaborateArrowFunction(node *ast.Node, source *Type, target *T
func (c *Checker) isWeakType(t *Type) bool {
if t.flags&TypeFlagsObject != 0 {
resolved := c.resolveStructuredTypeMembers(t)
return len(resolved.getSignatures()) == 0 && len(resolved.getIndexInfos()) == 0 && len(resolved.properties) > 0 && core.Every(resolved.properties, func(p *ast.Symbol) bool {
return len(resolved.getSignatures()) == 0 && len(resolved.getIndexInfos()) == 0 && len(c.getLayoutPropertiesOfType(t)) > 0 && core.Every(c.getLayoutPropertiesOfType(t), func(p *ast.Symbol) bool {
return p.Flags()&ast.SymbolFlagsOptional != 0
})
}
@@ -975,14 +975,16 @@ func (c *Checker) getUnmatchedProperties(source *Type, target *Type, requireOpti
}
func (c *Checker) getUnmatchedPropertiesWorker(source *Type, target *Type, requireOptionalProperties bool, matchDiscriminantProperties bool, propsOut *[]*ast.Symbol) *ast.Symbol {
properties := c.getPropertiesOfType(target)
for _, targetProp := range properties {
for _, targetProp := range c.getLayoutPropertiesOfType(target) {
// TODO: remove this when we support static private identifier fields and find other solutions to get privateNamesAndStaticFields test to pass
if isStaticPrivateIdentifierProperty(targetProp) {
continue
}
if requireOptionalProperties || targetProp.Flags()&ast.SymbolFlagsOptional == 0 && targetProp.CheckFlags()&ast.CheckFlagsPartial == 0 {
sourceProp := c.getPropertyOfType(source, targetProp.Name())
if sourceProp == nil || matchDiscriminantProperties {
targetProp = c.getPropertyOfType(target, targetProp.Name())
}
if sourceProp == nil {
if propsOut == nil {
return targetProp
+1 -1
View File
@@ -154,7 +154,7 @@ func (c *Checker) ForEachExportAndPropertyOfModule(moduleSymbol *ast.Symbol, cb
if reducedType.flags&TypeFlagsStructuredType == 0 {
return
}
for name, symbol := range c.resolveStructuredTypeMembers(reducedType).members {
for name, symbol := range c.resolveStructuredTypeMembers(reducedType).getMembers() {
if c.isNamedMember(symbol, name) {
cb(symbol, name)
}
+98 -1
View File
@@ -1143,6 +1143,82 @@ func (t *StructuredType) ConstructSignatures() []*Signature {
return slices.Clip(t.extra.signatures[t.extra.callSignatureCount:])
}
func (t *StructuredType) getMember(name string) *ast.Symbol {
if t.members != nil {
return t.members[name]
}
lazy := t.getLazyState()
if lazy == nil {
return nil
}
memberInfo := lazy.layout.memberInfoMap[name]
if memberInfo == nil {
return nil
}
return t.getPropertyAt(int(memberInfo.slotIndex))
}
func (t *StructuredType) getMembers() ast.SymbolTable {
if t.members == nil {
if properties := t.getProperties(); len(properties) != 0 {
t.members = make(ast.SymbolTable, len(properties))
for _, member := range properties {
t.members[member.Name()] = member
}
}
}
return t.members
}
func (t *StructuredType) getPropertyAt(index int) *ast.Symbol {
lazy := t.getLazyState()
if lazy == nil {
return t.properties[index]
}
if t.properties == nil {
t.properties = make([]*ast.Symbol, len(lazy.layout.memberInfos))
}
member := t.properties[index]
if member == nil {
memberInfo := lazy.layout.memberInfos[index]
if memberInfo.baseIndex < 0 {
member = t.checker.instantiateSymbol(memberInfo.symbol, lazy.mapper)
} else {
member = t.checker.getPropertyOfType(lazy.baseTypes[memberInfo.baseIndex], memberInfo.symbol.Name())
}
t.properties[index] = member
}
return member
}
func (t *StructuredType) getProperties() []*ast.Symbol {
if lazy := t.getLazyState(); lazy != nil && !lazy.propertiesResolved {
for i := range lazy.layout.memberInfos {
t.getPropertyAt(i)
}
lazy.propertiesResolved = true
}
return t.AsStructuredType().properties
}
func (t *StructuredType) hasProperties() bool {
if len(t.properties) != 0 {
return true
}
lazy := t.getLazyState()
if lazy == nil {
return false
}
return len(lazy.layout.memberInfos) != 0
}
func (t *StructuredType) getLazyState() *LazyState {
if t.objectFlags&(ObjectFlagsClassOrInterface|ObjectFlagsReference) != 0 {
return t.AsType().AsTypeReference().lazy
}
return nil
}
func (t *StructuredType) getSignatures() []*Signature {
if t.extra == nil {
return nil
@@ -1165,7 +1241,7 @@ func (t *StructuredType) ensureExtra() *structuredTypeExtra {
}
func (t *StructuredType) Properties() []*ast.Symbol {
return t.properties
return t.getProperties()
}
// Except for tuple type references and reverse mapped types, all object types have an associated symbol.
@@ -1216,6 +1292,27 @@ type TypeReference struct {
ObjectType
node *ast.Node // TypeReferenceNode | ArrayTypeNode | TupleTypeNode when deferred, else nil
resolvedTypeArguments []*Type
lazy *LazyState // Resolved member layout and instantiation state
}
type LazyState struct {
layout *MemberLayout
mapper *TypeMapper
baseTypes []*Type
propertiesResolved bool
}
type MemberLayout struct {
id uint32 // Unique identifier for the member layout
memberInfoMap map[string]*MemberInfo // MemberInfos keyed by property name
memberInfos []MemberInfo // MemberInfos in sorted order
layoutProperties []*ast.Symbol // Lazily created list of layout properties (symbols corresponding to memberInfos)
}
type MemberInfo struct {
symbol *ast.Symbol // Uninstantiated symbol
baseIndex int32 // Index of base type with symbol, or -1 if locally declared
slotIndex int32 // Index of resolved symbol in members array
}
func (t *TypeReference) AsTypeReference() *TypeReference { return t }
@@ -0,0 +1,52 @@
//// [tests/cases/compiler/lateBoundMemberLayoutReentrancy.ts] ////
//// [lateBoundMemberLayoutReentrancy.ts]
declare const rI: RI<"a">;
rI.x
interface RI<T extends "a" | "b"> {
x: T;
[rI.x]: "b";
}
declare const rI2: RI<"b">;
export const v1 = rI2.a;
export const v2 = rI.a;
export type K2 = keyof RI<"b">;
export const k: K2 = "a";
export const o: RI<"b"> = { x: "b", a: "b" };
declare const rC: RC<"a">;
rC.x
declare class RC<T extends "a" | "b"> {
x: T;
[rC.x]: "b";
}
declare const rC2: RC<"b">;
export const w1 = rC2.a;
export const w2 = rC.a;
//// [lateBoundMemberLayoutReentrancy.js]
rI.x;
export const v1 = rI2.a;
export const v2 = rI.a;
export const k = "a";
export const o = { x: "b", a: "b" };
rC.x;
export const w1 = rC2.a;
export const w2 = rC.a;
//// [lateBoundMemberLayoutReentrancy.d.ts]
declare const rI: RI<"a">;
interface RI<T extends "a" | "b"> {
x: T;
[rI.x]: "b";
}
export declare const v1: "b";
export declare const v2: "b";
export type K2 = keyof RI<"b">;
export declare const k: K2;
export declare const o: RI<"b">;
export declare const w1: "b";
export declare const w2: "b";
export {};
@@ -0,0 +1,95 @@
//// [tests/cases/compiler/lateBoundMemberLayoutReentrancy.ts] ////
=== lateBoundMemberLayoutReentrancy.ts ===
declare const rI: RI<"a">;
>rI : Symbol(rI, Decl(lateBoundMemberLayoutReentrancy.ts, 0, 13))
>RI : Symbol(RI, Decl(lateBoundMemberLayoutReentrancy.ts, 1, 4))
rI.x
>rI.x : Symbol(RI.x, Decl(lateBoundMemberLayoutReentrancy.ts, 2, 35))
>rI : Symbol(rI, Decl(lateBoundMemberLayoutReentrancy.ts, 0, 13))
>x : Symbol(RI.x, Decl(lateBoundMemberLayoutReentrancy.ts, 2, 35))
interface RI<T extends "a" | "b"> {
>RI : Symbol(RI, Decl(lateBoundMemberLayoutReentrancy.ts, 1, 4))
>T : Symbol(T, Decl(lateBoundMemberLayoutReentrancy.ts, 2, 13))
x: T;
>x : Symbol(RI.x, Decl(lateBoundMemberLayoutReentrancy.ts, 2, 35))
>T : Symbol(T, Decl(lateBoundMemberLayoutReentrancy.ts, 2, 13))
[rI.x]: "b";
>[rI.x] : Symbol(RI[rI.x], Decl(lateBoundMemberLayoutReentrancy.ts, 3, 9))
>rI.x : Symbol(RI.x, Decl(lateBoundMemberLayoutReentrancy.ts, 2, 35))
>rI : Symbol(rI, Decl(lateBoundMemberLayoutReentrancy.ts, 0, 13))
>x : Symbol(RI.x, Decl(lateBoundMemberLayoutReentrancy.ts, 2, 35))
}
declare const rI2: RI<"b">;
>rI2 : Symbol(rI2, Decl(lateBoundMemberLayoutReentrancy.ts, 6, 13))
>RI : Symbol(RI, Decl(lateBoundMemberLayoutReentrancy.ts, 1, 4))
export const v1 = rI2.a;
>v1 : Symbol(v1, Decl(lateBoundMemberLayoutReentrancy.ts, 7, 12))
>rI2.a : Symbol(RI[rI.x], Decl(lateBoundMemberLayoutReentrancy.ts, 3, 9))
>rI2 : Symbol(rI2, Decl(lateBoundMemberLayoutReentrancy.ts, 6, 13))
>a : Symbol(RI[rI.x], Decl(lateBoundMemberLayoutReentrancy.ts, 3, 9))
export const v2 = rI.a;
>v2 : Symbol(v2, Decl(lateBoundMemberLayoutReentrancy.ts, 8, 12))
>rI.a : Symbol(RI[rI.x], Decl(lateBoundMemberLayoutReentrancy.ts, 3, 9))
>rI : Symbol(rI, Decl(lateBoundMemberLayoutReentrancy.ts, 0, 13))
>a : Symbol(RI[rI.x], Decl(lateBoundMemberLayoutReentrancy.ts, 3, 9))
export type K2 = keyof RI<"b">;
>K2 : Symbol(K2, Decl(lateBoundMemberLayoutReentrancy.ts, 8, 23))
>RI : Symbol(RI, Decl(lateBoundMemberLayoutReentrancy.ts, 1, 4))
export const k: K2 = "a";
>k : Symbol(k, Decl(lateBoundMemberLayoutReentrancy.ts, 10, 12))
>K2 : Symbol(K2, Decl(lateBoundMemberLayoutReentrancy.ts, 8, 23))
export const o: RI<"b"> = { x: "b", a: "b" };
>o : Symbol(o, Decl(lateBoundMemberLayoutReentrancy.ts, 11, 12))
>RI : Symbol(RI, Decl(lateBoundMemberLayoutReentrancy.ts, 1, 4))
>x : Symbol(x, Decl(lateBoundMemberLayoutReentrancy.ts, 11, 27))
>a : Symbol(a, Decl(lateBoundMemberLayoutReentrancy.ts, 11, 35))
declare const rC: RC<"a">;
>rC : Symbol(rC, Decl(lateBoundMemberLayoutReentrancy.ts, 13, 13))
>RC : Symbol(RC, Decl(lateBoundMemberLayoutReentrancy.ts, 14, 4))
rC.x
>rC.x : Symbol(RC.x, Decl(lateBoundMemberLayoutReentrancy.ts, 15, 39))
>rC : Symbol(rC, Decl(lateBoundMemberLayoutReentrancy.ts, 13, 13))
>x : Symbol(RC.x, Decl(lateBoundMemberLayoutReentrancy.ts, 15, 39))
declare class RC<T extends "a" | "b"> {
>RC : Symbol(RC, Decl(lateBoundMemberLayoutReentrancy.ts, 14, 4))
>T : Symbol(T, Decl(lateBoundMemberLayoutReentrancy.ts, 15, 17))
x: T;
>x : Symbol(RC.x, Decl(lateBoundMemberLayoutReentrancy.ts, 15, 39))
>T : Symbol(T, Decl(lateBoundMemberLayoutReentrancy.ts, 15, 17))
[rC.x]: "b";
>[rC.x] : Symbol(RC[rC.x], Decl(lateBoundMemberLayoutReentrancy.ts, 16, 9))
>rC.x : Symbol(RC.x, Decl(lateBoundMemberLayoutReentrancy.ts, 15, 39))
>rC : Symbol(rC, Decl(lateBoundMemberLayoutReentrancy.ts, 13, 13))
>x : Symbol(RC.x, Decl(lateBoundMemberLayoutReentrancy.ts, 15, 39))
}
declare const rC2: RC<"b">;
>rC2 : Symbol(rC2, Decl(lateBoundMemberLayoutReentrancy.ts, 19, 13))
>RC : Symbol(RC, Decl(lateBoundMemberLayoutReentrancy.ts, 14, 4))
export const w1 = rC2.a;
>w1 : Symbol(w1, Decl(lateBoundMemberLayoutReentrancy.ts, 20, 12))
>rC2.a : Symbol(RC[rC.x], Decl(lateBoundMemberLayoutReentrancy.ts, 16, 9))
>rC2 : Symbol(rC2, Decl(lateBoundMemberLayoutReentrancy.ts, 19, 13))
>a : Symbol(RC[rC.x], Decl(lateBoundMemberLayoutReentrancy.ts, 16, 9))
export const w2 = rC.a;
>w2 : Symbol(w2, Decl(lateBoundMemberLayoutReentrancy.ts, 21, 12))
>rC.a : Symbol(RC[rC.x], Decl(lateBoundMemberLayoutReentrancy.ts, 16, 9))
>rC : Symbol(rC, Decl(lateBoundMemberLayoutReentrancy.ts, 13, 13))
>a : Symbol(RC[rC.x], Decl(lateBoundMemberLayoutReentrancy.ts, 16, 9))
@@ -0,0 +1,86 @@
//// [tests/cases/compiler/lateBoundMemberLayoutReentrancy.ts] ////
=== lateBoundMemberLayoutReentrancy.ts ===
declare const rI: RI<"a">;
>rI : RI<"a">
rI.x
>rI.x : "a"
>rI : RI<"a">
>x : "a"
interface RI<T extends "a" | "b"> {
x: T;
>x : T
[rI.x]: "b";
>[rI.x] : "b"
>rI.x : "a"
>rI : RI<"a">
>x : "a"
}
declare const rI2: RI<"b">;
>rI2 : RI<"b">
export const v1 = rI2.a;
>v1 : "b"
>rI2.a : "b"
>rI2 : RI<"b">
>a : "b"
export const v2 = rI.a;
>v2 : "b"
>rI.a : "b"
>rI : RI<"a">
>a : "b"
export type K2 = keyof RI<"b">;
>K2 : keyof RI<"b">
export const k: K2 = "a";
>k : keyof RI<"b">
>"a" : "a"
export const o: RI<"b"> = { x: "b", a: "b" };
>o : RI<"b">
>{ x: "b", a: "b" } : { x: "b"; a: "b"; }
>x : "b"
>"b" : "b"
>a : "b"
>"b" : "b"
declare const rC: RC<"a">;
>rC : RC<"a">
rC.x
>rC.x : "a"
>rC : RC<"a">
>x : "a"
declare class RC<T extends "a" | "b"> {
>RC : RC<T>
x: T;
>x : T
[rC.x]: "b";
>[rC.x] : "b"
>rC.x : "a"
>rC : RC<"a">
>x : "a"
}
declare const rC2: RC<"b">;
>rC2 : RC<"b">
export const w1 = rC2.a;
>w1 : "b"
>rC2.a : "b"
>rC2 : RC<"b">
>a : "b"
export const w2 = rC.a;
>w2 : "b"
>rC.a : "b"
>rC : RC<"a">
>a : "b"
@@ -0,0 +1,146 @@
//// [tests/cases/compiler/lazyInheritedMemberLookup.ts] ////
=== lazyInheritedMemberLookup.ts ===
// Inherited members are looked up individually before the members of each type are enumerated.
interface Grand<T> {
>Grand : Symbol(Grand, Decl(lazyInheritedMemberLookup.ts, 0, 0))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 2, 16))
grand: T;
>grand : Symbol(Grand.grand, Decl(lazyInheritedMemberLookup.ts, 2, 20))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 2, 16))
shared: T;
>shared : Symbol(Grand.shared, Decl(lazyInheritedMemberLookup.ts, 3, 13))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 2, 16))
}
type Mixin<T> = { mixin: T };
>Mixin : Symbol(Mixin, Decl(lazyInheritedMemberLookup.ts, 5, 1))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 6, 11))
>mixin : Symbol(mixin, Decl(lazyInheritedMemberLookup.ts, 6, 17))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 6, 11))
type Fixed = { fixed: string };
>Fixed : Symbol(Fixed, Decl(lazyInheritedMemberLookup.ts, 6, 29))
>fixed : Symbol(fixed, Decl(lazyInheritedMemberLookup.ts, 7, 14))
interface Base<T> extends Grand<T[]> {
>Base : Symbol(Base, Decl(lazyInheritedMemberLookup.ts, 7, 31))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 8, 15))
>Grand : Symbol(Grand, Decl(lazyInheritedMemberLookup.ts, 0, 0))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 8, 15))
base: T;
>base : Symbol(Base.base, Decl(lazyInheritedMemberLookup.ts, 8, 38))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 8, 15))
}
interface Derived<T> extends Base<T>, Mixin<T>, Fixed {
>Derived : Symbol(Derived, Decl(lazyInheritedMemberLookup.ts, 10, 1))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 11, 18))
>Base : Symbol(Base, Decl(lazyInheritedMemberLookup.ts, 7, 31))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 11, 18))
>Mixin : Symbol(Mixin, Decl(lazyInheritedMemberLookup.ts, 5, 1))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 11, 18))
>Fixed : Symbol(Fixed, Decl(lazyInheritedMemberLookup.ts, 6, 29))
shared: T[];
>shared : Symbol(Derived.shared, Decl(lazyInheritedMemberLookup.ts, 11, 55))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 11, 18))
derived: T;
>derived : Symbol(Derived.derived, Decl(lazyInheritedMemberLookup.ts, 12, 16))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 11, 18))
}
class C<T> {
>C : Symbol(C, Decl(lazyInheritedMemberLookup.ts, 14, 1))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 15, 8))
declared!: T;
>declared : Symbol(C.declared, Decl(lazyInheritedMemberLookup.ts, 15, 12))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 15, 8))
}
class D<T> extends C<T[]> implements Derived<T> {
>D : Symbol(D, Decl(lazyInheritedMemberLookup.ts, 17, 1))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
>C : Symbol(C, Decl(lazyInheritedMemberLookup.ts, 14, 1))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
>Derived : Symbol(Derived, Decl(lazyInheritedMemberLookup.ts, 10, 1))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
grand!: T[];
>grand : Symbol(D.grand, Decl(lazyInheritedMemberLookup.ts, 18, 49))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
shared!: T[];
>shared : Symbol(D.shared, Decl(lazyInheritedMemberLookup.ts, 19, 16))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
mixin!: T;
>mixin : Symbol(D.mixin, Decl(lazyInheritedMemberLookup.ts, 20, 17))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
fixed!: string;
>fixed : Symbol(D.fixed, Decl(lazyInheritedMemberLookup.ts, 21, 14))
base!: T;
>base : Symbol(D.base, Decl(lazyInheritedMemberLookup.ts, 22, 19))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
derived!: T;
>derived : Symbol(D.derived, Decl(lazyInheritedMemberLookup.ts, 23, 13))
>T : Symbol(T, Decl(lazyInheritedMemberLookup.ts, 18, 8))
}
declare const d: Derived<number>;
>d : Symbol(d, Decl(lazyInheritedMemberLookup.ts, 27, 13))
>Derived : Symbol(Derived, Decl(lazyInheritedMemberLookup.ts, 10, 1))
const grand = d.grand;
>grand : Symbol(grand, Decl(lazyInheritedMemberLookup.ts, 28, 5))
>d.grand : Symbol(Grand.grand, Decl(lazyInheritedMemberLookup.ts, 2, 20))
>d : Symbol(d, Decl(lazyInheritedMemberLookup.ts, 27, 13))
>grand : Symbol(Grand.grand, Decl(lazyInheritedMemberLookup.ts, 2, 20))
const mixin = d.mixin;
>mixin : Symbol(mixin, Decl(lazyInheritedMemberLookup.ts, 29, 5))
>d.mixin : Symbol(mixin, Decl(lazyInheritedMemberLookup.ts, 6, 17))
>d : Symbol(d, Decl(lazyInheritedMemberLookup.ts, 27, 13))
>mixin : Symbol(mixin, Decl(lazyInheritedMemberLookup.ts, 6, 17))
const fixed = d.fixed;
>fixed : Symbol(fixed, Decl(lazyInheritedMemberLookup.ts, 30, 5))
>d.fixed : Symbol(fixed, Decl(lazyInheritedMemberLookup.ts, 7, 14))
>d : Symbol(d, Decl(lazyInheritedMemberLookup.ts, 27, 13))
>fixed : Symbol(fixed, Decl(lazyInheritedMemberLookup.ts, 7, 14))
const shared = d.shared;
>shared : Symbol(shared, Decl(lazyInheritedMemberLookup.ts, 31, 5))
>d.shared : Symbol(Derived.shared, Decl(lazyInheritedMemberLookup.ts, 11, 55))
>d : Symbol(d, Decl(lazyInheritedMemberLookup.ts, 27, 13))
>shared : Symbol(Derived.shared, Decl(lazyInheritedMemberLookup.ts, 11, 55))
const all = { ...d };
>all : Symbol(all, Decl(lazyInheritedMemberLookup.ts, 32, 5))
>d : Symbol(d, Decl(lazyInheritedMemberLookup.ts, 27, 13))
declare const keys: { [K in keyof Derived<boolean>]: K };
>keys : Symbol(keys, Decl(lazyInheritedMemberLookup.ts, 33, 13))
>K : Symbol(K, Decl(lazyInheritedMemberLookup.ts, 33, 23))
>Derived : Symbol(Derived, Decl(lazyInheritedMemberLookup.ts, 10, 1))
>K : Symbol(K, Decl(lazyInheritedMemberLookup.ts, 33, 23))
declare const e: D<string>;
>e : Symbol(e, Decl(lazyInheritedMemberLookup.ts, 35, 13))
>D : Symbol(D, Decl(lazyInheritedMemberLookup.ts, 17, 1))
const declared = e.declared;
>declared : Symbol(declared, Decl(lazyInheritedMemberLookup.ts, 36, 5))
>e.declared : Symbol(C.declared, Decl(lazyInheritedMemberLookup.ts, 15, 12))
>e : Symbol(e, Decl(lazyInheritedMemberLookup.ts, 35, 13))
>declared : Symbol(C.declared, Decl(lazyInheritedMemberLookup.ts, 15, 12))
const allE = { ...e };
>allE : Symbol(allE, Decl(lazyInheritedMemberLookup.ts, 37, 5))
>e : Symbol(e, Decl(lazyInheritedMemberLookup.ts, 35, 13))
@@ -0,0 +1,109 @@
//// [tests/cases/compiler/lazyInheritedMemberLookup.ts] ////
=== lazyInheritedMemberLookup.ts ===
// Inherited members are looked up individually before the members of each type are enumerated.
interface Grand<T> {
grand: T;
>grand : T
shared: T;
>shared : T
}
type Mixin<T> = { mixin: T };
>Mixin : Mixin<T>
>mixin : T
type Fixed = { fixed: string };
>Fixed : Fixed
>fixed : string
interface Base<T> extends Grand<T[]> {
base: T;
>base : T
}
interface Derived<T> extends Base<T>, Mixin<T>, Fixed {
shared: T[];
>shared : T[]
derived: T;
>derived : T
}
class C<T> {
>C : C<T>
declared!: T;
>declared : T
}
class D<T> extends C<T[]> implements Derived<T> {
>D : D<T>
>C : C<T[]>
grand!: T[];
>grand : T[]
shared!: T[];
>shared : T[]
mixin!: T;
>mixin : T
fixed!: string;
>fixed : string
base!: T;
>base : T
derived!: T;
>derived : T
}
declare const d: Derived<number>;
>d : Derived<number>
const grand = d.grand;
>grand : number[]
>d.grand : number[]
>d : Derived<number>
>grand : number[]
const mixin = d.mixin;
>mixin : number
>d.mixin : number
>d : Derived<number>
>mixin : number
const fixed = d.fixed;
>fixed : string
>d.fixed : string
>d : Derived<number>
>fixed : string
const shared = d.shared;
>shared : number[]
>d.shared : number[]
>d : Derived<number>
>shared : number[]
const all = { ...d };
>all : { grand: number[]; mixin: number; fixed: string; base: number; shared: number[]; derived: number; }
>{ ...d } : { grand: number[]; mixin: number; fixed: string; base: number; shared: number[]; derived: number; }
>d : Derived<number>
declare const keys: { [K in keyof Derived<boolean>]: K };
>keys : { grand: "grand"; mixin: "mixin"; fixed: "fixed"; base: "base"; shared: "shared"; derived: "derived"; }
declare const e: D<string>;
>e : D<string>
const declared = e.declared;
>declared : string[]
>e.declared : string[]
>e : D<string>
>declared : string[]
const allE = { ...e };
>allE : { declared: string[]; grand: string[]; shared: string[]; mixin: string; fixed: string; base: string; derived: string; }
>{ ...e } : { declared: string[]; grand: string[]; shared: string[]; mixin: string; fixed: string; base: string; derived: string; }
>e : D<string>
@@ -0,0 +1,45 @@
//// [tests/cases/compiler/namespaceImportOfCallableInterfaceExport.ts] ////
=== mod.d.ts ===
interface Base<T> {
>Base : Symbol(Base, Decl(mod.d.ts, 0, 0))
>T : Symbol(T, Decl(mod.d.ts, 0, 15))
value: T;
>value : Symbol(Base.value, Decl(mod.d.ts, 0, 19))
>T : Symbol(T, Decl(mod.d.ts, 0, 15))
}
interface Callable extends Base<string> {
>Callable : Symbol(Callable, Decl(mod.d.ts, 2, 1))
>Base : Symbol(Base, Decl(mod.d.ts, 0, 0))
(): void;
__esModule: true;
>__esModule : Symbol(Callable.__esModule, Decl(mod.d.ts, 4, 13))
other: number;
>other : Symbol(Callable.other, Decl(mod.d.ts, 5, 21))
}
declare const callable: Callable;
>callable : Symbol(callable, Decl(mod.d.ts, 8, 13))
>Callable : Symbol(Callable, Decl(mod.d.ts, 2, 1))
export = callable;
>callable : Symbol(callable, Decl(mod.d.ts, 8, 13))
=== main.ts ===
import * as ns from "./mod";
>ns : Symbol(ns, Decl(main.ts, 0, 6))
const value: string = ns.value;
>value : Symbol(value, Decl(main.ts, 1, 5))
>ns.value : Symbol(Base.value, Decl(mod.d.ts, 0, 19))
>ns : Symbol(ns, Decl(main.ts, 0, 6))
>value : Symbol(Base.value, Decl(mod.d.ts, 0, 19))
const other: number = ns.other;
>other : Symbol(other, Decl(main.ts, 2, 5))
>ns.other : Symbol(Callable.other, Decl(mod.d.ts, 5, 21))
>ns : Symbol(ns, Decl(main.ts, 0, 6))
>other : Symbol(Callable.other, Decl(mod.d.ts, 5, 21))
@@ -0,0 +1,38 @@
//// [tests/cases/compiler/namespaceImportOfCallableInterfaceExport.ts] ////
=== mod.d.ts ===
interface Base<T> {
value: T;
>value : T
}
interface Callable extends Base<string> {
(): void;
__esModule: true;
>__esModule : true
>true : true
other: number;
>other : number
}
declare const callable: Callable;
>callable : Callable
export = callable;
>callable : Callable
=== main.ts ===
import * as ns from "./mod";
>ns : { value: string; __esModule: true; other: number; }
const value: string = ns.value;
>value : string
>ns.value : string
>ns : { value: string; __esModule: true; other: number; }
>value : string
const other: number = ns.other;
>other : number
>ns.other : number
>ns : { value: string; __esModule: true; other: number; }
>other : number
@@ -0,0 +1,67 @@
//// [tests/cases/compiler/sharedMemberLayoutGenericBase1.ts] ////
=== sharedMemberLayoutGenericBase1.ts ===
function factory<T extends object>(ctor: new () => T) {
>factory : Symbol(factory, Decl(sharedMemberLayoutGenericBase1.ts, 0, 0))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase1.ts, 0, 17))
>ctor : Symbol(ctor, Decl(sharedMemberLayoutGenericBase1.ts, 0, 35))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase1.ts, 0, 17))
class Base extends ctor {}
>Base : Symbol(Base, Decl(sharedMemberLayoutGenericBase1.ts, 0, 55))
>ctor : Symbol(ctor, Decl(sharedMemberLayoutGenericBase1.ts, 0, 35))
class Derived extends Base {}
>Derived : Symbol(Derived, Decl(sharedMemberLayoutGenericBase1.ts, 1, 30))
>Base : Symbol(Base, Decl(sharedMemberLayoutGenericBase1.ts, 0, 55))
return Derived;
>Derived : Symbol(Derived, Decl(sharedMemberLayoutGenericBase1.ts, 1, 30))
}
class A { a = 1; }
>A : Symbol(A, Decl(sharedMemberLayoutGenericBase1.ts, 4, 1))
>a : Symbol(A.a, Decl(sharedMemberLayoutGenericBase1.ts, 6, 9))
class B { b = "b"; }
>B : Symbol(B, Decl(sharedMemberLayoutGenericBase1.ts, 6, 18))
>b : Symbol(B.b, Decl(sharedMemberLayoutGenericBase1.ts, 7, 9))
const DA = factory(A);
>DA : Symbol(DA, Decl(sharedMemberLayoutGenericBase1.ts, 9, 5))
>factory : Symbol(factory, Decl(sharedMemberLayoutGenericBase1.ts, 0, 0))
>A : Symbol(A, Decl(sharedMemberLayoutGenericBase1.ts, 4, 1))
const a = new DA();
>a : Symbol(a, Decl(sharedMemberLayoutGenericBase1.ts, 10, 5))
>DA : Symbol(DA, Decl(sharedMemberLayoutGenericBase1.ts, 9, 5))
const aValue: number = a.a;
>aValue : Symbol(aValue, Decl(sharedMemberLayoutGenericBase1.ts, 11, 5))
>a.a : Symbol(A.a, Decl(sharedMemberLayoutGenericBase1.ts, 6, 9))
>a : Symbol(a, Decl(sharedMemberLayoutGenericBase1.ts, 10, 5))
>a : Symbol(A.a, Decl(sharedMemberLayoutGenericBase1.ts, 6, 9))
const aAll = { ...a };
>aAll : Symbol(aAll, Decl(sharedMemberLayoutGenericBase1.ts, 12, 5))
>a : Symbol(a, Decl(sharedMemberLayoutGenericBase1.ts, 10, 5))
const DB = factory(B);
>DB : Symbol(DB, Decl(sharedMemberLayoutGenericBase1.ts, 14, 5))
>factory : Symbol(factory, Decl(sharedMemberLayoutGenericBase1.ts, 0, 0))
>B : Symbol(B, Decl(sharedMemberLayoutGenericBase1.ts, 6, 18))
const b = new DB();
>b : Symbol(b, Decl(sharedMemberLayoutGenericBase1.ts, 15, 5))
>DB : Symbol(DB, Decl(sharedMemberLayoutGenericBase1.ts, 14, 5))
const bValue: string = b.b;
>bValue : Symbol(bValue, Decl(sharedMemberLayoutGenericBase1.ts, 16, 5))
>b.b : Symbol(B.b, Decl(sharedMemberLayoutGenericBase1.ts, 7, 9))
>b : Symbol(b, Decl(sharedMemberLayoutGenericBase1.ts, 15, 5))
>b : Symbol(B.b, Decl(sharedMemberLayoutGenericBase1.ts, 7, 9))
const bAll = { ...b };
>bAll : Symbol(bAll, Decl(sharedMemberLayoutGenericBase1.ts, 17, 5))
>b : Symbol(b, Decl(sharedMemberLayoutGenericBase1.ts, 15, 5))
@@ -0,0 +1,73 @@
//// [tests/cases/compiler/sharedMemberLayoutGenericBase1.ts] ////
=== sharedMemberLayoutGenericBase1.ts ===
function factory<T extends object>(ctor: new () => T) {
>factory : <T extends object>(ctor: new () => T) => typeof Derived
>ctor : new () => T
class Base extends ctor {}
>Base : Base
>ctor : T
class Derived extends Base {}
>Derived : Derived
>Base : Base
return Derived;
>Derived : typeof Derived
}
class A { a = 1; }
>A : A
>a : number
>1 : 1
class B { b = "b"; }
>B : B
>b : string
>"b" : "b"
const DA = factory(A);
>DA : typeof Derived
>factory(A) : typeof Derived
>factory : <T extends object>(ctor: new () => T) => typeof Derived
>A : typeof A
const a = new DA();
>a : factory.Derived
>new DA() : factory.Derived
>DA : typeof Derived
const aValue: number = a.a;
>aValue : number
>a.a : number
>a : factory.Derived
>a : number
const aAll = { ...a };
>aAll : { a: number; }
>{ ...a } : { a: number; }
>a : factory.Derived
const DB = factory(B);
>DB : typeof Derived
>factory(B) : typeof Derived
>factory : <T extends object>(ctor: new () => T) => typeof Derived
>B : typeof B
const b = new DB();
>b : factory.Derived
>new DB() : factory.Derived
>DB : typeof Derived
const bValue: string = b.b;
>bValue : string
>b.b : string
>b : factory.Derived
>b : string
const bAll = { ...b };
>bAll : { b: string; }
>{ ...b } : { b: string; }
>b : factory.Derived
@@ -0,0 +1,88 @@
//// [tests/cases/compiler/sharedMemberLayoutGenericBase2.ts] ////
=== sharedMemberLayoutGenericBase2.ts ===
declare function queryOptions<U>(): Omit<{
>queryOptions : Symbol(queryOptions, Decl(sharedMemberLayoutGenericBase2.ts, 0, 0))
>U : Symbol(U, Decl(sharedMemberLayoutGenericBase2.ts, 0, 30))
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
queryKey: string;
>queryKey : Symbol(queryKey, Decl(sharedMemberLayoutGenericBase2.ts, 0, 42))
queryFn: () => { slug: string };
>queryFn : Symbol(queryFn, Decl(sharedMemberLayoutGenericBase2.ts, 1, 21))
>slug : Symbol(slug, Decl(sharedMemberLayoutGenericBase2.ts, 2, 20))
}, keyof U>;
>U : Symbol(U, Decl(sharedMemberLayoutGenericBase2.ts, 0, 30))
// Keep the call before the interface declarations.
const resume = ensureQueryData(queryOptions());
>resume : Symbol(resume, Decl(sharedMemberLayoutGenericBase2.ts, 6, 5))
>ensureQueryData : Symbol(ensureQueryData, Decl(sharedMemberLayoutGenericBase2.ts, 19, 38))
>queryOptions : Symbol(queryOptions, Decl(sharedMemberLayoutGenericBase2.ts, 0, 0))
resume.slug;
>resume.slug : Symbol(slug, Decl(sharedMemberLayoutGenericBase2.ts, 2, 20))
>resume : Symbol(resume, Decl(sharedMemberLayoutGenericBase2.ts, 6, 5))
>slug : Symbol(slug, Decl(sharedMemberLayoutGenericBase2.ts, 2, 20))
interface QueryOptions<T, K> {
>QueryOptions : Symbol(QueryOptions, Decl(sharedMemberLayoutGenericBase2.ts, 7, 12))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 9, 23))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 9, 25))
queryKey?: K;
>queryKey : Symbol(QueryOptions.queryKey, Decl(sharedMemberLayoutGenericBase2.ts, 9, 30))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 9, 25))
queryFn?: () => T;
>queryFn : Symbol(QueryOptions.queryFn, Decl(sharedMemberLayoutGenericBase2.ts, 10, 17))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 9, 23))
}
type WithRequired<T> = T & { queryKey: {} };
>WithRequired : Symbol(WithRequired, Decl(sharedMemberLayoutGenericBase2.ts, 12, 1))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 13, 18))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 13, 18))
>queryKey : Symbol(queryKey, Decl(sharedMemberLayoutGenericBase2.ts, 13, 28))
interface FetchQueryOptions<T, K>
>FetchQueryOptions : Symbol(FetchQueryOptions, Decl(sharedMemberLayoutGenericBase2.ts, 13, 44))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 14, 28))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 14, 30))
extends WithRequired<QueryOptions<T, K>> {
>WithRequired : Symbol(WithRequired, Decl(sharedMemberLayoutGenericBase2.ts, 12, 1))
>QueryOptions : Symbol(QueryOptions, Decl(sharedMemberLayoutGenericBase2.ts, 7, 12))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 14, 28))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 14, 30))
initialPageParam?: never;
>initialPageParam : Symbol(FetchQueryOptions.initialPageParam, Decl(sharedMemberLayoutGenericBase2.ts, 15, 46))
}
interface EnsureQueryDataOptions<T, K>
>EnsureQueryDataOptions : Symbol(EnsureQueryDataOptions, Decl(sharedMemberLayoutGenericBase2.ts, 17, 1))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 18, 33))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 18, 35))
extends FetchQueryOptions<T, K> {}
>FetchQueryOptions : Symbol(FetchQueryOptions, Decl(sharedMemberLayoutGenericBase2.ts, 13, 44))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 18, 33))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 18, 35))
declare function ensureQueryData<T, K>(
>ensureQueryData : Symbol(ensureQueryData, Decl(sharedMemberLayoutGenericBase2.ts, 19, 38))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 21, 33))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 21, 35))
options: EnsureQueryDataOptions<T, K>
>options : Symbol(options, Decl(sharedMemberLayoutGenericBase2.ts, 21, 39))
>EnsureQueryDataOptions : Symbol(EnsureQueryDataOptions, Decl(sharedMemberLayoutGenericBase2.ts, 17, 1))
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 21, 33))
>K : Symbol(K, Decl(sharedMemberLayoutGenericBase2.ts, 21, 35))
): T;
>T : Symbol(T, Decl(sharedMemberLayoutGenericBase2.ts, 21, 33))
export {};
@@ -0,0 +1,57 @@
//// [tests/cases/compiler/sharedMemberLayoutGenericBase2.ts] ////
=== sharedMemberLayoutGenericBase2.ts ===
declare function queryOptions<U>(): Omit<{
>queryOptions : <U>() => Omit<{ queryKey: string; queryFn: () => { slug: string; }; }, keyof U>
queryKey: string;
>queryKey : string
queryFn: () => { slug: string };
>queryFn : () => { slug: string; }
>slug : string
}, keyof U>;
// Keep the call before the interface declarations.
const resume = ensureQueryData(queryOptions());
>resume : { slug: string; }
>ensureQueryData(queryOptions()) : { slug: string; }
>ensureQueryData : <T, K>(options: EnsureQueryDataOptions<T, K>) => T
>queryOptions() : Omit<{ queryKey: string; queryFn: () => { slug: string; }; }, never>
>queryOptions : <U>() => Omit<{ queryKey: string; queryFn: () => { slug: string; }; }, keyof U>
resume.slug;
>resume.slug : string
>resume : { slug: string; }
>slug : string
interface QueryOptions<T, K> {
queryKey?: K;
>queryKey : K | undefined
queryFn?: () => T;
>queryFn : (() => T) | undefined
}
type WithRequired<T> = T & { queryKey: {} };
>WithRequired : WithRequired<T>
>queryKey : {}
interface FetchQueryOptions<T, K>
extends WithRequired<QueryOptions<T, K>> {
initialPageParam?: never;
>initialPageParam : undefined
}
interface EnsureQueryDataOptions<T, K>
extends FetchQueryOptions<T, K> {}
declare function ensureQueryData<T, K>(
>ensureQueryData : <T, K>(options: EnsureQueryDataOptions<T, K>) => T
options: EnsureQueryDataOptions<T, K>
>options : EnsureQueryDataOptions<T, K>
): T;
export {};
@@ -0,0 +1,36 @@
sharedMemberLayoutThisIntersectionBase.ts(5,11): error TS2589: Type instantiation is excessively deep and possibly infinite.
sharedMemberLayoutThisIntersectionBase.ts(7,1): error TS2589: Type instantiation is excessively deep and possibly infinite.
sharedMemberLayoutThisIntersectionBase.ts(7,3): error TS2339: Property 'm' does not exist on type 'D<"b">'.
sharedMemberLayoutThisIntersectionBase.ts(10,7): error TS2589: Type instantiation is excessively deep and possibly infinite.
sharedMemberLayoutThisIntersectionBase.ts(12,1): error TS2589: Type instantiation is excessively deep and possibly infinite.
sharedMemberLayoutThisIntersectionBase.ts(12,3): error TS2339: Property 'm' does not exist on type 'C<"b">'.
==== sharedMemberLayoutThisIntersectionBase.ts (6 errors) ====
interface A { kind: string; m: this["kind"] }
interface B { m: "a" }
type AB = A & B;
interface D<T extends string> extends AB { kind: T }
~
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
declare let d: D<"b">;
d.m;
~~~
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
~
!!! error TS2339: Property 'm' does not exist on type 'D<"b">'.
declare const ABCtor: new () => AB;
class C<T extends string> extends ABCtor { declare kind: T }
~
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
declare let c: C<"b">;
c.m;
~~~
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
~
!!! error TS2339: Property 'm' does not exist on type 'C<"b">'.
export {};
@@ -0,0 +1,51 @@
//// [tests/cases/compiler/sharedMemberLayoutThisIntersectionBase.ts] ////
=== sharedMemberLayoutThisIntersectionBase.ts ===
interface A { kind: string; m: this["kind"] }
>A : Symbol(A, Decl(sharedMemberLayoutThisIntersectionBase.ts, 0, 0))
>kind : Symbol(A.kind, Decl(sharedMemberLayoutThisIntersectionBase.ts, 0, 13))
>m : Symbol(A.m, Decl(sharedMemberLayoutThisIntersectionBase.ts, 0, 27))
interface B { m: "a" }
>B : Symbol(B, Decl(sharedMemberLayoutThisIntersectionBase.ts, 0, 45))
>m : Symbol(B.m, Decl(sharedMemberLayoutThisIntersectionBase.ts, 1, 13))
type AB = A & B;
>AB : Symbol(AB, Decl(sharedMemberLayoutThisIntersectionBase.ts, 1, 22))
>A : Symbol(A, Decl(sharedMemberLayoutThisIntersectionBase.ts, 0, 0))
>B : Symbol(B, Decl(sharedMemberLayoutThisIntersectionBase.ts, 0, 45))
interface D<T extends string> extends AB { kind: T }
>D : Symbol(D, Decl(sharedMemberLayoutThisIntersectionBase.ts, 2, 16))
>T : Symbol(T, Decl(sharedMemberLayoutThisIntersectionBase.ts, 4, 12))
>AB : Symbol(AB, Decl(sharedMemberLayoutThisIntersectionBase.ts, 1, 22))
>kind : Symbol(D.kind, Decl(sharedMemberLayoutThisIntersectionBase.ts, 4, 42))
>T : Symbol(T, Decl(sharedMemberLayoutThisIntersectionBase.ts, 4, 12))
declare let d: D<"b">;
>d : Symbol(d, Decl(sharedMemberLayoutThisIntersectionBase.ts, 5, 11))
>D : Symbol(D, Decl(sharedMemberLayoutThisIntersectionBase.ts, 2, 16))
d.m;
>d : Symbol(d, Decl(sharedMemberLayoutThisIntersectionBase.ts, 5, 11))
declare const ABCtor: new () => AB;
>ABCtor : Symbol(ABCtor, Decl(sharedMemberLayoutThisIntersectionBase.ts, 8, 13))
>AB : Symbol(AB, Decl(sharedMemberLayoutThisIntersectionBase.ts, 1, 22))
class C<T extends string> extends ABCtor { declare kind: T }
>C : Symbol(C, Decl(sharedMemberLayoutThisIntersectionBase.ts, 8, 35))
>T : Symbol(T, Decl(sharedMemberLayoutThisIntersectionBase.ts, 9, 8))
>ABCtor : Symbol(ABCtor, Decl(sharedMemberLayoutThisIntersectionBase.ts, 8, 13))
>kind : Symbol(C.kind, Decl(sharedMemberLayoutThisIntersectionBase.ts, 9, 42))
>T : Symbol(T, Decl(sharedMemberLayoutThisIntersectionBase.ts, 9, 8))
declare let c: C<"b">;
>c : Symbol(c, Decl(sharedMemberLayoutThisIntersectionBase.ts, 10, 11))
>C : Symbol(C, Decl(sharedMemberLayoutThisIntersectionBase.ts, 8, 35))
c.m;
>c : Symbol(c, Decl(sharedMemberLayoutThisIntersectionBase.ts, 10, 11))
export {};
@@ -0,0 +1,42 @@
//// [tests/cases/compiler/sharedMemberLayoutThisIntersectionBase.ts] ////
=== sharedMemberLayoutThisIntersectionBase.ts ===
interface A { kind: string; m: this["kind"] }
>kind : string
>m : this["kind"]
interface B { m: "a" }
>m : "a"
type AB = A & B;
>AB : AB
interface D<T extends string> extends AB { kind: T }
>kind : T
declare let d: D<"b">;
>d : D<"b">
d.m;
>d.m : any
>d : D<"b">
>m : any
declare const ABCtor: new () => AB;
>ABCtor : new () => AB
class C<T extends string> extends ABCtor { declare kind: T }
>C : C<T>
>ABCtor : A & B
>kind : T
declare let c: C<"b">;
>c : C<"b">
c.m;
>c.m : any
>c : C<"b">
>m : any
export {};
@@ -0,0 +1,18 @@
sharedMemberLayoutTupleBases.ts(4,11): error TS2430: Interface 'FromTuple<T>' incorrectly extends interface '[number, ...T]'.
==== sharedMemberLayoutTupleBases.ts (1 errors) ====
// Each tuple base can have a different target, and so a different member layout.
type Prefixed<T extends unknown[]> = [number, ...T];
interface FromTuple<T extends unknown[]> extends Prefixed<T> {}
~~~~~~~~~
!!! error TS2430: Interface 'FromTuple<T>' incorrectly extends interface '[number, ...T]'.
declare const generic: FromTuple<unknown[]>;
const genericFirst = generic[0];
const genericAll = { ...generic };
declare const fixed: FromTuple<[string]>;
const fixedSecond = fixed[1];
const fixedAll = { ...fixed };
@@ -0,0 +1,43 @@
//// [tests/cases/compiler/sharedMemberLayoutTupleBases.ts] ////
=== sharedMemberLayoutTupleBases.ts ===
// Each tuple base can have a different target, and so a different member layout.
type Prefixed<T extends unknown[]> = [number, ...T];
>Prefixed : Symbol(Prefixed, Decl(sharedMemberLayoutTupleBases.ts, 0, 0))
>T : Symbol(T, Decl(sharedMemberLayoutTupleBases.ts, 2, 14))
>T : Symbol(T, Decl(sharedMemberLayoutTupleBases.ts, 2, 14))
interface FromTuple<T extends unknown[]> extends Prefixed<T> {}
>FromTuple : Symbol(FromTuple, Decl(sharedMemberLayoutTupleBases.ts, 2, 52))
>T : Symbol(T, Decl(sharedMemberLayoutTupleBases.ts, 3, 20))
>Prefixed : Symbol(Prefixed, Decl(sharedMemberLayoutTupleBases.ts, 0, 0))
>T : Symbol(T, Decl(sharedMemberLayoutTupleBases.ts, 3, 20))
declare const generic: FromTuple<unknown[]>;
>generic : Symbol(generic, Decl(sharedMemberLayoutTupleBases.ts, 4, 13))
>FromTuple : Symbol(FromTuple, Decl(sharedMemberLayoutTupleBases.ts, 2, 52))
const genericFirst = generic[0];
>genericFirst : Symbol(genericFirst, Decl(sharedMemberLayoutTupleBases.ts, 5, 5))
>generic : Symbol(generic, Decl(sharedMemberLayoutTupleBases.ts, 4, 13))
>0 : Symbol(0)
const genericAll = { ...generic };
>genericAll : Symbol(genericAll, Decl(sharedMemberLayoutTupleBases.ts, 6, 5))
>generic : Symbol(generic, Decl(sharedMemberLayoutTupleBases.ts, 4, 13))
declare const fixed: FromTuple<[string]>;
>fixed : Symbol(fixed, Decl(sharedMemberLayoutTupleBases.ts, 7, 13))
>FromTuple : Symbol(FromTuple, Decl(sharedMemberLayoutTupleBases.ts, 2, 52))
const fixedSecond = fixed[1];
>fixedSecond : Symbol(fixedSecond, Decl(sharedMemberLayoutTupleBases.ts, 8, 5))
>fixed : Symbol(fixed, Decl(sharedMemberLayoutTupleBases.ts, 7, 13))
>1 : Symbol(1)
const fixedAll = { ...fixed };
>fixedAll : Symbol(fixedAll, Decl(sharedMemberLayoutTupleBases.ts, 9, 5))
>fixed : Symbol(fixed, Decl(sharedMemberLayoutTupleBases.ts, 7, 13))
@@ -0,0 +1,38 @@
//// [tests/cases/compiler/sharedMemberLayoutTupleBases.ts] ////
=== sharedMemberLayoutTupleBases.ts ===
// Each tuple base can have a different target, and so a different member layout.
type Prefixed<T extends unknown[]> = [number, ...T];
>Prefixed : [number, ...T]
interface FromTuple<T extends unknown[]> extends Prefixed<T> {}
declare const generic: FromTuple<unknown[]>;
>generic : FromTuple<unknown[]>
const genericFirst = generic[0];
>genericFirst : number
>generic[0] : number
>generic : FromTuple<unknown[]>
>0 : 0
const genericAll = { ...generic };
>genericAll : { [n: number]: unknown; toString(): string; toLocaleString(): string; toLocaleString(locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string; pop(): unknown; push(...items: unknown[]): number; concat(...items: ConcatArray<unknown>[]): unknown[]; concat(...items: unknown[]): unknown[]; join(separator?: string): string; reverse(): unknown[]; shift(): unknown; slice(start?: number, end?: number): unknown[]; sort(compareFn?: ((a: unknown, b: unknown) => number) | undefined): FromTuple<unknown[]>; splice(start: number, deleteCount?: number): unknown[]; splice(start: number, deleteCount: number, ...items: unknown[]): unknown[]; unshift(...items: unknown[]): number; indexOf(searchElement: unknown, fromIndex?: number): number; lastIndexOf(searchElement: unknown, fromIndex?: number): number; every<S extends unknown>(predicate: (value: unknown, index: number, array: unknown[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thisArg?: any): boolean; some(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: unknown, index: number, array: unknown[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: unknown, index: number, array: unknown[]) => U, thisArg?: any): U[]; filter<S extends unknown>(predicate: (value: unknown, index: number, array: unknown[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thisArg?: any): unknown[]; reduce(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown): unknown; reduce(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown, initialValue: unknown): unknown; reduce<U>(callbackfn: (previousValue: U, currentValue: unknown, currentIndex: number, array: unknown[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown): unknown; reduceRight(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown, initialValue: unknown): unknown; reduceRight<U>(callbackfn: (previousValue: U, currentValue: unknown, currentIndex: number, array: unknown[]) => U, initialValue: U): U; find<S extends unknown>(predicate: (value: unknown, index: number, obj: unknown[]) => value is S, thisArg?: any): S | undefined; find(predicate: (value: unknown, index: number, obj: unknown[]) => unknown, thisArg?: any): unknown; findIndex(predicate: (value: unknown, index: number, obj: unknown[]) => unknown, thisArg?: any): number; fill(value: unknown, start?: number, end?: number): FromTuple<unknown[]>; copyWithin(target: number, start: number, end?: number): FromTuple<unknown[]>; [Symbol.iterator](): ArrayIterator<unknown>; entries(): ArrayIterator<[number, unknown]>; keys(): ArrayIterator<number>; values(): ArrayIterator<unknown>; [Symbol.unscopables]: { [x: number]: boolean | undefined; length?: boolean | undefined; toString?: boolean | undefined; toLocaleString?: boolean | undefined; pop?: boolean | undefined; push?: boolean | undefined; concat?: boolean | undefined; join?: boolean | undefined; reverse?: boolean | undefined; shift?: boolean | undefined; slice?: boolean | undefined; sort?: boolean | undefined; splice?: boolean | undefined; unshift?: boolean | undefined; indexOf?: boolean | undefined; lastIndexOf?: boolean | undefined; every?: boolean | undefined; some?: boolean | undefined; forEach?: boolean | undefined; map?: boolean | undefined; filter?: boolean | undefined; reduce?: boolean | undefined; reduceRight?: boolean | undefined; find?: boolean | undefined; findIndex?: boolean | undefined; fill?: boolean | undefined; copyWithin?: boolean | undefined; [Symbol.iterator]?: boolean | undefined; entries?: boolean | undefined; keys?: boolean | undefined; values?: boolean | undefined; readonly [Symbol.unscopables]?: boolean | undefined; includes?: boolean | undefined; flatMap?: boolean | undefined; flat?: boolean | undefined; at?: boolean | undefined; findLast?: boolean | undefined; findLastIndex?: boolean | undefined; toReversed?: boolean | undefined; toSorted?: boolean | undefined; toSpliced?: boolean | undefined; with?: boolean | undefined; }; includes(searchElement: unknown, fromIndex?: number): boolean; flatMap<U, This = undefined>(callback: (this: This, value: unknown, index: number, array: unknown[]) => U | readonly U[], thisArg?: This | undefined): U[]; flat<A, D extends number = 1>(this: A, depth?: D | undefined): FlatArray<A, D>[]; at(index: number): unknown; findLast<S extends unknown>(predicate: (value: unknown, index: number, array: unknown[]) => value is S, thisArg?: any): S | undefined; findLast(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thisArgLine truncated
>{ ...generic } : { [n: number]: unknown; toString(): string; toLocaleString(): string; toLocaleString(locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string; pop(): unknown; push(...items: unknown[]): number; concat(...items: ConcatArray<unknown>[]): unknown[]; concat(...items: unknown[]): unknown[]; join(separator?: string): string; reverse(): unknown[]; shift(): unknown; slice(start?: number, end?: number): unknown[]; sort(compareFn?: ((a: unknown, b: unknown) => number) | undefined): FromTuple<unknown[]>; splice(start: number, deleteCount?: number): unknown[]; splice(start: number, deleteCount: number, ...items: unknown[]): unknown[]; unshift(...items: unknown[]): number; indexOf(searchElement: unknown, fromIndex?: number): number; lastIndexOf(searchElement: unknown, fromIndex?: number): number; every<S extends unknown>(predicate: (value: unknown, index: number, array: unknown[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thisArg?: any): boolean; some(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: unknown, index: number, array: unknown[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: unknown, index: number, array: unknown[]) => U, thisArg?: any): U[]; filter<S extends unknown>(predicate: (value: unknown, index: number, array: unknown[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thisArg?: any): unknown[]; reduce(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown): unknown; reduce(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown, initialValue: unknown): unknown; reduce<U>(callbackfn: (previousValue: U, currentValue: unknown, currentIndex: number, array: unknown[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown): unknown; reduceRight(callbackfn: (previousValue: unknown, currentValue: unknown, currentIndex: number, array: unknown[]) => unknown, initialValue: unknown): unknown; reduceRight<U>(callbackfn: (previousValue: U, currentValue: unknown, currentIndex: number, array: unknown[]) => U, initialValue: U): U; find<S extends unknown>(predicate: (value: unknown, index: number, obj: unknown[]) => value is S, thisArg?: any): S | undefined; find(predicate: (value: unknown, index: number, obj: unknown[]) => unknown, thisArg?: any): unknown; findIndex(predicate: (value: unknown, index: number, obj: unknown[]) => unknown, thisArg?: any): number; fill(value: unknown, start?: number, end?: number): FromTuple<unknown[]>; copyWithin(target: number, start: number, end?: number): FromTuple<unknown[]>; [Symbol.iterator](): ArrayIterator<unknown>; entries(): ArrayIterator<[number, unknown]>; keys(): ArrayIterator<number>; values(): ArrayIterator<unknown>; [Symbol.unscopables]: { [x: number]: boolean | undefined; length?: boolean | undefined; toString?: boolean | undefined; toLocaleString?: boolean | undefined; pop?: boolean | undefined; push?: boolean | undefined; concat?: boolean | undefined; join?: boolean | undefined; reverse?: boolean | undefined; shift?: boolean | undefined; slice?: boolean | undefined; sort?: boolean | undefined; splice?: boolean | undefined; unshift?: boolean | undefined; indexOf?: boolean | undefined; lastIndexOf?: boolean | undefined; every?: boolean | undefined; some?: boolean | undefined; forEach?: boolean | undefined; map?: boolean | undefined; filter?: boolean | undefined; reduce?: boolean | undefined; reduceRight?: boolean | undefined; find?: boolean | undefined; findIndex?: boolean | undefined; fill?: boolean | undefined; copyWithin?: boolean | undefined; [Symbol.iterator]?: boolean | undefined; entries?: boolean | undefined; keys?: boolean | undefined; values?: boolean | undefined; readonly [Symbol.unscopables]?: boolean | undefined; includes?: boolean | undefined; flatMap?: boolean | undefined; flat?: boolean | undefined; at?: boolean | undefined; findLast?: boolean | undefined; findLastIndex?: boolean | undefined; toReversed?: boolean | undefined; toSorted?: boolean | undefined; toSpliced?: boolean | undefined; with?: boolean | undefined; }; includes(searchElement: unknown, fromIndex?: number): boolean; flatMap<U, This = undefined>(callback: (this: This, value: unknown, index: number, array: unknown[]) => U | readonly U[], thisArg?: This | undefined): U[]; flat<A, D extends number = 1>(this: A, depth?: D | undefined): FlatArray<A, D>[]; at(index: number): unknown; findLast<S extends unknown>(predicate: (value: unknown, index: number, array: unknown[]) => value is S, thisArg?: any): S | undefined; findLast(predicate: (value: unknown, index: number, array: unknown[]) => unknown, thiLine truncated
>generic : FromTuple<unknown[]>
declare const fixed: FromTuple<[string]>;
>fixed : FromTuple<[string]>
const fixedSecond = fixed[1];
>fixedSecond : string
>fixed[1] : string
>fixed : FromTuple<[string]>
>1 : 1
const fixedAll = { ...fixed };
>fixedAll : { [n: number]: string | number; toString(): string; toLocaleString(): string; toLocaleString(locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string; pop(): string | number | undefined; push(...items: (string | number)[]): number; concat(...items: ConcatArray<string | number>[]): (string | number)[]; concat(...items: (string | number | ConcatArray<string | number>)[]): (string | number)[]; join(separator?: string): string; reverse(): (string | number)[]; shift(): string | number | undefined; slice(start?: number, end?: number): (string | number)[]; sort(compareFn?: ((a: string | number, b: string | number) => number) | undefined): FromTuple<[string]>; splice(start: number, deleteCount?: number): (string | number)[]; splice(start: number, deleteCount: number, ...items: (string | number)[]): (string | number)[]; unshift(...items: (string | number)[]): number; indexOf(searchElement: string | number, fromIndex?: number): number; lastIndexOf(searchElement: string | number, fromIndex?: number): number; every<S extends string | number>(predicate: (value: string | number, index: number, array: (string | number)[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: string | number, index: number, array: (string | number)[]) => unknown, thisArg?: any): boolean; some(predicate: (value: string | number, index: number, array: (string | number)[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: string | number, index: number, array: (string | number)[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: string | number, index: number, array: (string | number)[]) => U, thisArg?: any): U[]; filter<S extends string | number>(predicate: (value: string | number, index: number, array: (string | number)[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: string | number, index: number, array: (string | number)[]) => unknown, thisArg?: any): (string | number)[]; reduce(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number): string | number; reduce(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number, initialValue: string | number): string | number; reduce<U>(callbackfn: (previousValue: U, currentValue: string | number, currentIndex: number, array: (string | number)[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number): string | number; reduceRight(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number, initialValue: string | number): string | number; reduceRight<U>(callbackfn: (previousValue: U, currentValue: string | number, currentIndex: number, array: (string | number)[]) => U, initialValue: U): U; find<S extends string | number>(predicate: (value: string | number, index: number, obj: (string | number)[]) => value is S, thisArg?: any): S | undefined; find(predicate: (value: string | number, index: number, obj: (string | number)[]) => unknown, thisArg?: any): string | number | undefined; findIndex(predicate: (value: string | number, index: number, obj: (string | number)[]) => unknown, thisArg?: any): number; fill(value: string | number, start?: number, end?: number): FromTuple<[string]>; copyWithin(target: number, start: number, end?: number): FromTuple<[string]>; [Symbol.iterator](): ArrayIterator<string | number>; entries(): ArrayIterator<[number, string | number]>; keys(): ArrayIterator<number>; values(): ArrayIterator<string | number>; [Symbol.unscopables]: { [x: number]: boolean | undefined; length?: boolean | undefined; toString?: boolean | undefined; toLocaleString?: boolean | undefined; pop?: boolean | undefined; push?: boolean | undefined; concat?: boolean | undefined; join?: boolean | undefined; reverse?: boolean | undefined; shift?: boolean | undefined; slice?: boolean | undefined; sort?: boolean | undefined; splice?: boolean | undefined; unshift?: boolean | undefined; indexOf?: boolean | undefined; lastIndexOf?: boolean | undefined; every?: boolean | undefined; some?: boolean | undefined; forEach?: boolean | undefined; map?: boolean | undefined; filter?: boolean | undefined; reduce?: boolean | undefined; reduceRight?: boolean | undefined; find?: boolean | undefined; findIndex?: boolean | undefined; fill?: boolean | undefined; copyWithin?: boolean | undefined; [Symbol.iterator]?: boolean | undefined; entries?: boolean | undefined; keys?: boolean | undefined; values?: boolean | undefined; readonly [Symbol.unscopables]?: boolean | undefined; includes?: boolean | undefined; flatMap?: boolean | undefined; flat?: boolean | undefined; at?: boolean | undefined; findLast?: boolean | undefined; findLastIndex?: boolLine truncated
>{ ...fixed } : { [n: number]: string | number; toString(): string; toLocaleString(): string; toLocaleString(locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string; pop(): string | number | undefined; push(...items: (string | number)[]): number; concat(...items: ConcatArray<string | number>[]): (string | number)[]; concat(...items: (string | number | ConcatArray<string | number>)[]): (string | number)[]; join(separator?: string): string; reverse(): (string | number)[]; shift(): string | number | undefined; slice(start?: number, end?: number): (string | number)[]; sort(compareFn?: ((a: string | number, b: string | number) => number) | undefined): FromTuple<[string]>; splice(start: number, deleteCount?: number): (string | number)[]; splice(start: number, deleteCount: number, ...items: (string | number)[]): (string | number)[]; unshift(...items: (string | number)[]): number; indexOf(searchElement: string | number, fromIndex?: number): number; lastIndexOf(searchElement: string | number, fromIndex?: number): number; every<S extends string | number>(predicate: (value: string | number, index: number, array: (string | number)[]) => value is S, thisArg?: any): this is S[]; every(predicate: (value: string | number, index: number, array: (string | number)[]) => unknown, thisArg?: any): boolean; some(predicate: (value: string | number, index: number, array: (string | number)[]) => unknown, thisArg?: any): boolean; forEach(callbackfn: (value: string | number, index: number, array: (string | number)[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: string | number, index: number, array: (string | number)[]) => U, thisArg?: any): U[]; filter<S extends string | number>(predicate: (value: string | number, index: number, array: (string | number)[]) => value is S, thisArg?: any): S[]; filter(predicate: (value: string | number, index: number, array: (string | number)[]) => unknown, thisArg?: any): (string | number)[]; reduce(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number): string | number; reduce(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number, initialValue: string | number): string | number; reduce<U>(callbackfn: (previousValue: U, currentValue: string | number, currentIndex: number, array: (string | number)[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number): string | number; reduceRight(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number, initialValue: string | number): string | number; reduceRight<U>(callbackfn: (previousValue: U, currentValue: string | number, currentIndex: number, array: (string | number)[]) => U, initialValue: U): U; find<S extends string | number>(predicate: (value: string | number, index: number, obj: (string | number)[]) => value is S, thisArg?: any): S | undefined; find(predicate: (value: string | number, index: number, obj: (string | number)[]) => unknown, thisArg?: any): string | number | undefined; findIndex(predicate: (value: string | number, index: number, obj: (string | number)[]) => unknown, thisArg?: any): number; fill(value: string | number, start?: number, end?: number): FromTuple<[string]>; copyWithin(target: number, start: number, end?: number): FromTuple<[string]>; [Symbol.iterator](): ArrayIterator<string | number>; entries(): ArrayIterator<[number, string | number]>; keys(): ArrayIterator<number>; values(): ArrayIterator<string | number>; [Symbol.unscopables]: { [x: number]: boolean | undefined; length?: boolean | undefined; toString?: boolean | undefined; toLocaleString?: boolean | undefined; pop?: boolean | undefined; push?: boolean | undefined; concat?: boolean | undefined; join?: boolean | undefined; reverse?: boolean | undefined; shift?: boolean | undefined; slice?: boolean | undefined; sort?: boolean | undefined; splice?: boolean | undefined; unshift?: boolean | undefined; indexOf?: boolean | undefined; lastIndexOf?: boolean | undefined; every?: boolean | undefined; some?: boolean | undefined; forEach?: boolean | undefined; map?: boolean | undefined; filter?: boolean | undefined; reduce?: boolean | undefined; reduceRight?: boolean | undefined; find?: boolean | undefined; findIndex?: boolean | undefined; fill?: boolean | undefined; copyWithin?: boolean | undefined; [Symbol.iterator]?: boolean | undefined; entries?: boolean | undefined; keys?: boolean | undefined; values?: boolean | undefined; readonly [Symbol.unscopables]?: boolean | undefined; includes?: boolean | undefined; flatMap?: boolean | undefined; flat?: boolean | undefined; at?: boolean | undefined; findLast?: boolean | undefined; findLastIndex?: Line truncated
>fixed : FromTuple<[string]>
@@ -11,16 +11,14 @@ arityAndOrderCompatibility01.ts(23,5): error TS2322: Type '{ 0: string; 1: numbe
arityAndOrderCompatibility01.ts(24,5): error TS2322: Type '[string, number]' is not assignable to type '[number]'.
Source has 2 element(s) but target allows only 1.
arityAndOrderCompatibility01.ts(25,5): error TS2322: Type 'StrNum' is not assignable to type '[number]'.
The types returned by 'pop()' are incompatible between these types.
Type 'string | number | undefined' is not assignable to type 'number | undefined'.
Type 'string' is not assignable to type 'number'.
Types of property '0' are incompatible.
Type 'string' is not assignable to type 'number'.
arityAndOrderCompatibility01.ts(26,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
arityAndOrderCompatibility01.ts(27,5): error TS2322: Type '[string, number]' is not assignable to type '[string]'.
Source has 2 element(s) but target allows only 1.
arityAndOrderCompatibility01.ts(28,5): error TS2322: Type 'StrNum' is not assignable to type '[string]'.
The types returned by 'pop()' are incompatible between these types.
Type 'string | number | undefined' is not assignable to type 'string | undefined'.
Type 'number' is not assignable to type 'string'.
Types of property 'length' are incompatible.
Type '2' is not assignable to type '1'.
arityAndOrderCompatibility01.ts(29,5): error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
arityAndOrderCompatibility01.ts(30,5): error TS2322: Type '[string, number]' is not assignable to type '[number, string]'.
Type at position 0 in source is not compatible with type at position 0 in target.
@@ -80,9 +78,8 @@ arityAndOrderCompatibility01.ts(32,5): error TS2322: Type '{ 0: string; 1: numbe
var l2: [number] = y;
~~
!!! error TS2322: Type 'StrNum' is not assignable to type '[number]'.
!!! error TS2322: The types returned by 'pop()' are incompatible between these types.
!!! error TS2322: Type 'string | number | undefined' is not assignable to type 'number | undefined'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: Types of property '0' are incompatible.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
var l3: [number] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[number]'.
@@ -93,9 +90,8 @@ arityAndOrderCompatibility01.ts(32,5): error TS2322: Type '{ 0: string; 1: numbe
var m2: [string] = y;
~~
!!! error TS2322: Type 'StrNum' is not assignable to type '[string]'.
!!! error TS2322: The types returned by 'pop()' are incompatible between these types.
!!! error TS2322: Type 'string | number | undefined' is not assignable to type 'string | undefined'.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! error TS2322: Types of property 'length' are incompatible.
!!! error TS2322: Type '2' is not assignable to type '1'.
var m3: [string] = z;
~~
!!! error TS2322: Type '{ 0: string; 1: number; length: 2; }' is not assignable to type '[string]'.
@@ -0,0 +1,26 @@
// @target: esnext
// @strict: true
// @declaration: true
declare const rI: RI<"a">;
rI.x
interface RI<T extends "a" | "b"> {
x: T;
[rI.x]: "b";
}
declare const rI2: RI<"b">;
export const v1 = rI2.a;
export const v2 = rI.a;
export type K2 = keyof RI<"b">;
export const k: K2 = "a";
export const o: RI<"b"> = { x: "b", a: "b" };
declare const rC: RC<"a">;
rC.x
declare class RC<T extends "a" | "b"> {
x: T;
[rC.x]: "b";
}
declare const rC2: RC<"b">;
export const w1 = rC2.a;
export const w2 = rC.a;
@@ -0,0 +1,41 @@
// @strict: true
// @noEmit: true
// Inherited members are looked up individually before the members of each type are enumerated.
interface Grand<T> {
grand: T;
shared: T;
}
type Mixin<T> = { mixin: T };
type Fixed = { fixed: string };
interface Base<T> extends Grand<T[]> {
base: T;
}
interface Derived<T> extends Base<T>, Mixin<T>, Fixed {
shared: T[];
derived: T;
}
class C<T> {
declared!: T;
}
class D<T> extends C<T[]> implements Derived<T> {
grand!: T[];
shared!: T[];
mixin!: T;
fixed!: string;
base!: T;
derived!: T;
}
declare const d: Derived<number>;
const grand = d.grand;
const mixin = d.mixin;
const fixed = d.fixed;
const shared = d.shared;
const all = { ...d };
declare const keys: { [K in keyof Derived<boolean>]: K };
declare const e: D<string>;
const declared = e.declared;
const allE = { ...e };
@@ -0,0 +1,20 @@
// @module: commonjs
// @esModuleInterop: true,false
// @noEmit: true
// @filename: mod.d.ts
interface Base<T> {
value: T;
}
interface Callable extends Base<string> {
(): void;
__esModule: true;
other: number;
}
declare const callable: Callable;
export = callable;
// @filename: main.ts
import * as ns from "./mod";
const value: string = ns.value;
const other: number = ns.other;
@@ -0,0 +1,21 @@
// @strict: true
// @noEmit: true
function factory<T extends object>(ctor: new () => T) {
class Base extends ctor {}
class Derived extends Base {}
return Derived;
}
class A { a = 1; }
class B { b = "b"; }
const DA = factory(A);
const a = new DA();
const aValue: number = a.a;
const aAll = { ...a };
const DB = factory(B);
const b = new DB();
const bValue: string = b.b;
const bAll = { ...b };
@@ -0,0 +1,30 @@
// @strict: true
// @target: esnext
// @noEmit: true
declare function queryOptions<U>(): Omit<{
queryKey: string;
queryFn: () => { slug: string };
}, keyof U>;
// Keep the call before the interface declarations.
const resume = ensureQueryData(queryOptions());
resume.slug;
interface QueryOptions<T, K> {
queryKey?: K;
queryFn?: () => T;
}
type WithRequired<T> = T & { queryKey: {} };
interface FetchQueryOptions<T, K>
extends WithRequired<QueryOptions<T, K>> {
initialPageParam?: never;
}
interface EnsureQueryDataOptions<T, K>
extends FetchQueryOptions<T, K> {}
declare function ensureQueryData<T, K>(
options: EnsureQueryDataOptions<T, K>
): T;
export {};
@@ -0,0 +1,17 @@
// @strict: true
// @noEmit: true
interface A { kind: string; m: this["kind"] }
interface B { m: "a" }
type AB = A & B;
interface D<T extends string> extends AB { kind: T }
declare let d: D<"b">;
d.m;
declare const ABCtor: new () => AB;
class C<T extends string> extends ABCtor { declare kind: T }
declare let c: C<"b">;
c.m;
export {};
@@ -0,0 +1,14 @@
// @strict: true
// @noEmit: true
// Each tuple base can have a different target, and so a different member layout.
type Prefixed<T extends unknown[]> = [number, ...T];
interface FromTuple<T extends unknown[]> extends Prefixed<T> {}
declare const generic: FromTuple<unknown[]>;
const genericFirst = generic[0];
const genericAll = { ...generic };
declare const fixed: FromTuple<[string]>;
const fixedSecond = fixed[1];
const fixedAll = { ...fixed };