(target *Type, elementTypes []*Type, objectFlags ObjectFlags)
| 23209 | } |
| 23210 | |
| 23211 | func (c *Checker) createNormalizedTupleTypeEx(target *Type, elementTypes []*Type, objectFlags ObjectFlags) *Type { |
| 23212 | d := target.AsTupleType() |
| 23213 | if d.combinedFlags&ElementFlagsNonRequired == 0 { |
| 23214 | // No need to normalize when we only have regular required elements |
| 23215 | return c.createTypeReferenceEx(target, elementTypes, objectFlags) |
| 23216 | } |
| 23217 | if d.combinedFlags&ElementFlagsVariadic != 0 { |
| 23218 | for i, e := range elementTypes { |
| 23219 | if i < len(d.elementInfos) && d.elementInfos[i].flags&ElementFlagsVariadic != 0 && e.flags&(TypeFlagsNever|TypeFlagsUnion) != 0 { |
| 23220 | // Transform [A, ...(X | Y | Z)] into [A, ...X] | [A, ...Y] | [A, ...Z] |
| 23221 | checkTypes := core.MapIndex(elementTypes, func(t *Type, i int) *Type { |
| 23222 | if i < len(d.elementInfos) && d.elementInfos[i].flags&ElementFlagsVariadic != 0 { |
| 23223 | return t |
| 23224 | } |
| 23225 | return c.unknownType |
| 23226 | }) |
| 23227 | if c.checkCrossProductUnion(checkTypes) { |
| 23228 | return c.mapType(e, func(t *Type) *Type { |
| 23229 | return c.createNormalizedTupleTypeEx(target, core.ReplaceElement(elementTypes, i, t), objectFlags) |
| 23230 | }) |
| 23231 | } |
| 23232 | } |
| 23233 | } |
| 23234 | } |
| 23235 | // We have optional, rest, or variadic elements that may need normalizing. Normalization ensures that all variadic |
| 23236 | // elements are generic and that the tuple type has one of the following layouts, disregarding variadic elements: |
| 23237 | // (1) Zero or more required elements, followed by zero or more optional elements, followed by zero or one rest element. |
| 23238 | // (2) Zero or more required elements, followed by a rest element, followed by zero or more required elements. |
| 23239 | // In either layout, zero or more generic variadic elements may be present at any location. |
| 23240 | // Note that the element types may contain an extra 'this' type argument that we want to ignore during normalization |
| 23241 | // and then just append to the normalized element types. |
| 23242 | n := &TupleNormalizer{} |
| 23243 | if !n.normalize(c, elementTypes[:len(d.elementInfos)], d.elementInfos) { |
| 23244 | return c.errorType |
| 23245 | } |
| 23246 | if len(elementTypes) > len(d.elementInfos) { |
| 23247 | n.types = append(n.types, elementTypes[len(d.elementInfos)]) |
| 23248 | } |
| 23249 | tupleTarget := c.getTupleTargetType(n.infos, d.readonly) |
| 23250 | switch { |
| 23251 | case tupleTarget == c.emptyGenericType: |
| 23252 | return c.emptyObjectType |
| 23253 | case len(n.types) != 0: |
| 23254 | return c.createTypeReferenceEx(tupleTarget, n.types, objectFlags) |
| 23255 | } |
| 23256 | return tupleTarget |
| 23257 | } |
| 23258 | |
| 23259 | func (c *Checker) createNormalizedTupleType(target *Type, elementTypes []*Type) *Type { |
| 23260 | return c.createNormalizedTupleTypeEx(target, elementTypes, ObjectFlagsNone) |
no test coverage detected