Remove spread types, leaving spread syntax/emit

Spreads are still typed, but cannot be created from a non-object type.
Tests still need to be updated.
This commit is contained in:
Nathan Shively-Sanders 2016-11-02 16:26:34 -07:00
parent f65dd2101c
commit 334820c357
6 changed files with 57 additions and 354 deletions

View File

@ -113,7 +113,6 @@ namespace ts {
const tupleTypes: GenericType[] = [];
const unionTypes = createMap<UnionType>();
const intersectionTypes = createMap<IntersectionType>();
const spreadTypes = createMap<SpreadType>();
const stringLiteralTypes = createMap<LiteralType>();
const numericLiteralTypes = createMap<LiteralType>();
const evolvingArrayTypes: EvolvingArrayType[] = [];
@ -2244,9 +2243,6 @@ namespace ts {
else if (type.flags & TypeFlags.UnionOrIntersection) {
writeUnionOrIntersectionType(<UnionOrIntersectionType>type, nextFlags);
}
else if (type.flags & TypeFlags.Spread) {
writeSpreadType(<SpreadType>type);
}
else if (getObjectFlags(type) & ObjectFlags.Anonymous) {
writeAnonymousType(<ObjectType>type, nextFlags);
}
@ -2362,48 +2358,6 @@ namespace ts {
}
}
function writeSpreadType(type: SpreadType) {
writePunctuation(writer, SyntaxKind.OpenBraceToken);
writer.writeLine();
writer.increaseIndent();
writeSpreadTypeWorker(type, /*atEnd*/true, type.symbol);
writer.decreaseIndent();
writePunctuation(writer, SyntaxKind.CloseBraceToken);
}
function writeSpreadTypeWorker(type: SpreadType, atEnd: boolean, container: Symbol): void {
if (type.left.flags & TypeFlags.Spread) {
writeSpreadTypeWorker(type.left as SpreadType, /*atEnd*/false, container);
}
else {
const saveInObjectTypeLiteral = inObjectTypeLiteral;
inObjectTypeLiteral = true;
writeObjectLiteralType(resolveStructuredTypeMembers(type.left as ResolvedType));
inObjectTypeLiteral = saveInObjectTypeLiteral;
}
if (type.right.symbol === container) {
// if type.right was written as part of the spread type, don't surround with ...{ }.
// this gives { a: number, ... T } instead of { ...{ a: number }, ...T }
const saveInObjectTypeLiteral = inObjectTypeLiteral;
inObjectTypeLiteral = true;
writeObjectLiteralType(resolveStructuredTypeMembers(type.right as ResolvedType));
inObjectTypeLiteral = saveInObjectTypeLiteral;
}
else {
writePunctuation(writer, SyntaxKind.DotDotDotToken);
writeType(type.right, TypeFormatFlags.None);
if (atEnd) {
writeSpace(writer);
}
else {
writePunctuation(writer, SyntaxKind.SemicolonToken);
writer.writeLine();
}
}
}
function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) {
const symbol = type.symbol;
if (symbol) {
@ -3623,7 +3577,6 @@ namespace ts {
links.type = getUnionType([getTypeOfSymbol(links.leftSpread), getTypeOfSymbol(links.rightSpread)]);
}
return links.type;
}
function getTargetType(type: Type): Type {
@ -4567,10 +4520,6 @@ namespace ts {
return type.resolvedApparentType;
}
function getApparentTypeOfSpread(type: SpreadType) {
return getApparentType(type.right);
}
/**
* For a type parameter, return the base constraint of the type parameter. For the string, number,
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@ -4578,7 +4527,6 @@ namespace ts {
*/
function getApparentType(type: Type): Type {
let t = type.flags & TypeFlags.TypeParameter ? getApparentTypeOfTypeParameter(<TypeParameter>type) : type;
t = t.flags & TypeFlags.Spread ? getApparentTypeOfSpread(type as SpreadType) : t;
return t.flags & TypeFlags.StringLike ? globalStringType :
t.flags & TypeFlags.NumberLike ? globalNumberType :
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
@ -4640,7 +4588,7 @@ namespace ts {
propTypes.push(type);
}
const result = <TransientSymbol>createSymbol(SymbolFlags.Property | SymbolFlags.Transient | SymbolFlags.SyntheticProperty | commonFlags, name);
result.syntheticKind === SyntheticSymbolKind.UnionOrIntersection;
result.syntheticKind = SyntheticSymbolKind.UnionOrIntersection;
result.containingType = containingType;
result.hasNonUniformType = hasNonUniformType;
result.isPartial = isPartial;
@ -5917,12 +5865,6 @@ namespace ts {
function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: Node, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
const hasSpread = (node.kind === SyntaxKind.TypeLiteral &&
find((node as TypeLiteralNode).members, elt => elt.kind === SyntaxKind.SpreadTypeElement));
if (hasSpread) {
return getTypeFromSpreadTypeLiteral(node, aliasSymbol, aliasTypeArguments);
}
// Deferred resolution of members is handled by resolveObjectTypeMembers
if (isEmpty(node.symbol.members) && !aliasSymbol && !aliasTypeArguments) {
links.resolvedType = emptyTypeLiteralType;
@ -5937,187 +5879,56 @@ namespace ts {
return links.resolvedType;
}
function getTypeFromSpreadTypeLiteral(node: Node, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
let spread: Type = emptyObjectType;
let members: Map<Symbol>;
let stringIndexInfo: IndexInfo;
let numberIndexInfo: IndexInfo;
for (const member of (node as TypeLiteralNode).members) {
if (member.kind === SyntaxKind.SpreadTypeElement) {
if (members) {
const type = createAnonymousType(node.symbol, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
spread = getSpreadType(spread, type, node.symbol, aliasSymbol, aliasTypeArguments);
members = undefined;
stringIndexInfo = undefined;
numberIndexInfo = undefined;
}
const type = getTypeFromTypeNode((member as SpreadTypeElement).type);
spread = getSpreadType(spread, type, node.symbol, aliasSymbol, aliasTypeArguments);
}
else if (member.kind !== SyntaxKind.IndexSignature &&
member.kind !== SyntaxKind.CallSignature &&
member.kind !== SyntaxKind.ConstructSignature) {
// it is an error for spread types to include index, call or construct signatures
const flags = SymbolFlags.Property | SymbolFlags.Transient | (member.questionToken ? SymbolFlags.Optional : 0);
const text = getTextOfPropertyName(member.name);
const symbol = <TransientSymbol>createSymbol(flags, text);
symbol.declarations = [member];
symbol.valueDeclaration = member;
symbol.type = getTypeFromTypeNodeNoAlias((member as IndexSignatureDeclaration | PropertySignature | MethodSignature).type);
if (!members) {
members = createMap<Symbol>();
}
members[symbol.name] = symbol;
}
}
if (members || stringIndexInfo || numberIndexInfo) {
const type = createAnonymousType(node.symbol, members || emptySymbols, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
spread = getSpreadType(spread, type, node.symbol, aliasSymbol, aliasTypeArguments);
}
return spread;
}
/**
* Since the source of spread types are object literals and type literals, which are not binary,
* this function should be called in a left folding style, with left = previous result of getSpreadType
* and right = the new element to be spread.
*/
function getSpreadType(left: Type, right: Type, symbol: Symbol, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
const id = getTypeListId([left, right]);
if (id in spreadTypes) {
return spreadTypes[id];
}
// any spreads to any
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
return anyType;
}
// flatten intersections to objects if all member types are objects
if (left.flags & TypeFlags.Intersection) {
left = resolveObjectIntersection(left as IntersectionType);
}
if (right.flags & TypeFlags.Intersection) {
right = resolveObjectIntersection(right as IntersectionType);
}
// distribute unions
if (left.flags & TypeFlags.Union) {
const spreads = map((left as UnionType).types,
t => getSpreadType(t, right, symbol, aliasSymbol, aliasTypeArguments));
return getUnionType(spreads, /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
if (right.flags & TypeFlags.Union) {
const spreads = map((right as UnionType).types,
t => getSpreadType(left, t, symbol, aliasSymbol, aliasTypeArguments));
return getUnionType(spreads, /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
// skip primitives
if (left.flags & TypeFlags.Primitive && right.flags & TypeFlags.Primitive) {
return emptyObjectType;
}
else if (left.flags & TypeFlags.Primitive) {
return right;
}
else if (right.flags & TypeFlags.Primitive) {
return left;
}
// spread simplifications
if (left.flags & TypeFlags.Spread &&
right.flags & TypeFlags.TypeParameter &&
(left as SpreadType).right.flags & TypeFlags.TypeParameter &&
right.symbol === (left as SpreadType).right.symbol) {
// for types like T ... T, just return ... T
return left;
}
if (left.flags & TypeFlags.Spread &&
right.flags & TypeFlags.Object &&
(left as SpreadType).right.flags & TypeFlags.Object) {
// simplify two adjacent object types: T ... { x } ... { y } becomes T ... { x, y }
const simplified = getSpreadType(right, (left as SpreadType).right, symbol, aliasSymbol, aliasTypeArguments);
return getSpreadType((left as SpreadType).left, simplified, symbol, aliasSymbol, aliasTypeArguments);
}
if (right.flags & TypeFlags.Spread) {
// spread is right associative and associativity applies, so transform
// (T ... U) ... V to T ... (U ... V)
const rspread = right as SpreadType;
if (rspread.left === emptyObjectType) {
// ... U ... ({} ... T) => ... U ... T
return getSpreadType(left, rspread.right, symbol, aliasSymbol, aliasTypeArguments);
}
return getSpreadType(getSpreadType(left, rspread.left, symbol, aliasSymbol, aliasTypeArguments),
rspread.right, symbol, aliasSymbol, aliasTypeArguments);
}
// create an object type if left and right are both objects,
// otherwise create a spread type
if (right.flags & TypeFlags.Object && left.flags & TypeFlags.Object) {
const members = createMap<Symbol>();
const skippedPrivateMembers = createMap<boolean>();
const stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.String), getIndexInfoOfType(right, IndexKind.String));
const numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.Number), getIndexInfoOfType(right, IndexKind.Number));
const isFromSpread = right.symbol !== symbol;
for (const rightProp of getPropertiesOfType(right)) {
if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) {
skippedPrivateMembers[rightProp.name] = true;
}
else if (!(rightProp.flags & SymbolFlags.Method && isFromSpread) &&
!(rightProp.flags & SymbolFlags.SetAccessor && !(rightProp.flags & SymbolFlags.GetAccessor))) {
// skip methods from spreads and accessors with setters but no getters
members[rightProp.name] = rightProp;
}
}
for (const leftProp of getPropertiesOfType(left)) {
if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor)
|| leftProp.name in skippedPrivateMembers) {
continue;
}
if (leftProp.name in members) {
const rightProp = members[leftProp.name];
if (rightProp.flags & SymbolFlags.Optional) {
const declarations: Declaration[] = concatenate(leftProp.declarations, rightProp.declarations);
const flags = SymbolFlags.Property | SymbolFlags.Transient | SymbolFlags.SyntheticProperty | (leftProp.flags & SymbolFlags.Optional);
const result = <TransientSymbol>createSymbol(flags, leftProp.name);
result.syntheticKind = SyntheticSymbolKind.Spread;
result.leftSpread = leftProp;
result.rightSpread = rightProp;
result.declarations = declarations;
if (declarations.length) {
result.valueDeclaration = declarations[0];
}
result.isReadonly = isReadonlySymbol(leftProp) || isReadonlySymbol(rightProp);
members[leftProp.name] = result;
}
}
else {
members[leftProp.name] = leftProp;
}
}
return createAnonymousType(symbol, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
}
const spread = spreadTypes[id] = createType(TypeFlags.Spread) as SpreadType;
Debug.assert(!!(left.flags & (TypeFlags.Spread | TypeFlags.Object)), "Left flags: " + left.flags.toString(2));
Debug.assert(!!(right.flags & (TypeFlags.TypeParameter | TypeFlags.Intersection | TypeFlags.Index | TypeFlags.IndexedAccess | TypeFlags.Object)), "Right flags: " + right.flags.toString(2));
spread.symbol = symbol;
spread.left = left as SpreadType | ResolvedType;
spread.right = right as TypeParameter | IntersectionType | IndexType | IndexedAccessType | ResolvedType;
spread.aliasSymbol = aliasSymbol;
spread.aliasTypeArguments = aliasTypeArguments;
return spread;
}
function resolveObjectIntersection(intersection: IntersectionType): IntersectionType | ResolvedType {
if (find(intersection.types, t => !(t.flags & TypeFlags.Object))) {
return intersection;
}
const properties = getPropertiesOfType(intersection);
function getSpreadType(left: Type, right: Type, symbol: Symbol): ResolvedType {
Debug.assert(!!(left.flags & TypeFlags.Object) && !!(right.flags & TypeFlags.Object), "Only object types may be spread.");
const members = createMap<Symbol>();
for (const property of properties) {
members[property.name] = property;
const skippedPrivateMembers = createMap<boolean>();
const stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.String), getIndexInfoOfType(right, IndexKind.String));
const numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, IndexKind.Number), getIndexInfoOfType(right, IndexKind.Number));
const isFromSpread = right.symbol !== symbol;
for (const rightProp of getPropertiesOfType(right)) {
if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) {
skippedPrivateMembers[rightProp.name] = true;
}
else if (!(rightProp.flags & SymbolFlags.Method && isFromSpread) &&
!(rightProp.flags & SymbolFlags.SetAccessor && !(rightProp.flags & SymbolFlags.GetAccessor))) {
// skip methods from spreads and accessors with setters but no getters
members[rightProp.name] = rightProp;
}
}
const stringIndex = getIndexInfoOfType(intersection, IndexKind.String);
const numberIndex = getIndexInfoOfType(intersection, IndexKind.Number);
return createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndex, numberIndex);
for (const leftProp of getPropertiesOfType(left)) {
if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor)
|| leftProp.name in skippedPrivateMembers) {
continue;
}
if (leftProp.name in members) {
const rightProp = members[leftProp.name];
if (rightProp.flags & SymbolFlags.Optional) {
const declarations: Declaration[] = concatenate(leftProp.declarations, rightProp.declarations);
const flags = SymbolFlags.Property | SymbolFlags.Transient | SymbolFlags.SyntheticProperty | (leftProp.flags & SymbolFlags.Optional);
const result = <TransientSymbol>createSymbol(flags, leftProp.name);
result.syntheticKind = SyntheticSymbolKind.Spread;
result.leftSpread = leftProp;
result.rightSpread = rightProp;
result.declarations = declarations;
if (declarations.length) {
result.valueDeclaration = declarations[0];
}
result.isReadonly = isReadonlySymbol(leftProp) || isReadonlySymbol(rightProp);
members[leftProp.name] = result;
}
}
else {
members[leftProp.name] = leftProp;
}
}
return createAnonymousType(symbol, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
}
function createLiteralType(flags: TypeFlags, text: string) {
@ -6535,10 +6346,6 @@ namespace ts {
if (type.flags & TypeFlags.Intersection) {
return getIntersectionType(instantiateList((<IntersectionType>type).types, mapper, instantiateType), type.aliasSymbol, mapper.targetTypes);
}
if (type.flags & TypeFlags.Spread) {
const spread = type as SpreadType;
return getSpreadType(instantiateType(spread.left, mapper), instantiateType(spread.right, mapper), type.symbol, type.aliasSymbol, mapper.targetTypes);
}
if (type.flags & TypeFlags.Index) {
return getIndexType(instantiateType((<IndexType>type).type, mapper));
}
@ -7089,30 +6896,7 @@ namespace ts {
}
}
if (source.flags & TypeFlags.Spread && target.flags & TypeFlags.Spread) {
// you only see this for spreads with type parameters
if (!(spreadTypeRelatedTo(source as SpreadType, target as SpreadType, /*atRightEdge*/ true))) {
if (reportErrors) {
reportRelationError(headMessage, source, target);
}
return Ternary.False;
}
const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
const apparentSource = getApparentType(source);
if (result = objectTypeRelatedTo(apparentSource, source, getApparentType(target), reportStructuralErrors)) {
errorInfo = saveErrorInfo;
return result;
}
}
if (source.flags & TypeFlags.TypeParameter) {
if (target.flags & TypeFlags.Spread) {
// T is assignable to ...T
if (source.symbol === (target as SpreadType).right.symbol
&& (target as SpreadType).left === emptyObjectType) {
return Ternary.True;
}
}
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
if (!constraint || constraint.flags & TypeFlags.Any) {
@ -7164,32 +6948,6 @@ namespace ts {
return Ternary.False;
}
function spreadTypeRelatedTo(source: SpreadType, target: SpreadType, atRightEdge?: boolean): boolean {
// If the right side of a spread type is ObjectType, then the left side must be a Spread.
// Structural compatibility of the spreads' object types are checked separately in isRelatedTo,
// so just skip them for now.
if (source.right.flags & TypeFlags.Object || target.right.flags & TypeFlags.Object) {
return atRightEdge &&
spreadTypeRelatedTo(source.right.flags & TypeFlags.Object ? source.left as SpreadType : source,
target.right.flags & TypeFlags.Object ? target.left as SpreadType : target);
}
// If both right sides are type parameters, intersections, index types or indexed access types,
// then they must be identical for the spread types to be related.
// It also means that the left sides are either spread types or object types.
// if one left is object and the other is spread, that means the second has another type parameter. which isn't allowed
if (target.right !== source.right) {
return false;
}
if (source.left.flags & TypeFlags.Spread && target.left.flags & TypeFlags.Spread) {
// If the left sides are both spread types, then recursively check them.
return spreadTypeRelatedTo(source.left as SpreadType, target.left as SpreadType);
}
// If the left sides are both object types, then we should be at the end and both should be emptyObjectType.
// If not, we can't know what properties might have been overwritten, so fail.
return source.left === emptyObjectType && target.left === emptyObjectType;
}
function isIdenticalTo(source: Type, target: Type): Ternary {
let result: Ternary;
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) {
@ -11167,6 +10925,10 @@ namespace ts {
typeFlags = 0;
}
const type = checkExpression((memberDecl as SpreadElementExpression).expression);
if (!(type.flags & TypeFlags.Object)) {
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
return unknownType;
}
spread = getSpreadType(spread, type, node.symbol);
continue;
}
@ -15403,13 +15165,6 @@ namespace ts {
checkTypeForDuplicateIndexSignatures(node);
checkObjectTypeForDuplicateDeclarations(node);
}
if (find(node.members, p => p.kind === SyntaxKind.SpreadTypeElement)) {
for (const signature of filter(node.members, p => p.kind === SyntaxKind.IndexSignature ||
p.kind === SyntaxKind.CallSignature ||
p.kind === SyntaxKind.ConstructSignature)) {
error(signature, Diagnostics.Type_literals_with_spreads_cannot_contain_index_call_or_construct_signatures);
}
}
}
}
@ -17467,9 +17222,7 @@ namespace ts {
// perform property check if property or indexer is declared in 'type'
// this allows to rule out cases when both property and indexer are inherited from the base class
let errorNode: Node;
if (prop.valueDeclaration.name.kind === SyntaxKind.ComputedPropertyName ||
prop.parent === containingType.symbol ||
containingType.flags & TypeFlags.Spread) {
if (prop.valueDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) {
errorNode = prop.valueDeclaration;
}
else if (indexDeclaration) {
@ -20699,12 +20452,6 @@ namespace ts {
checkGrammarHeritageClause(heritageClause);
}
}
let result: TypeElement;
if (result = find(node.members, e => e.kind === SyntaxKind.SpreadTypeElement)) {
return grammarErrorOnNode(result, Diagnostics.Interface_declaration_cannot_contain_a_spread_property);
}
return false;
}

View File

@ -1138,13 +1138,6 @@ namespace ts {
writeLine();
}
function emitSpreadTypeElement(type: SpreadTypeElement) {
write("...");
emitType(type.type);
write(";");
writeLine();
}
function emitVariableDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration) {
// If we are emitting property it isn't moduleElement and hence we already know it needs to be emitted
// so there is no check needed to see if declaration is visible
@ -1729,8 +1722,6 @@ namespace ts {
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
return emitPropertyDeclaration(<PropertyDeclaration>node);
case SyntaxKind.SpreadTypeElement:
return emitSpreadTypeElement(node as SpreadTypeElement);
case SyntaxKind.EnumMember:
return emitEnumMemberDeclaration(<EnumMember>node);
case SyntaxKind.ExportAssignment:

View File

@ -1983,14 +1983,10 @@
"category": "Error",
"code": 2697
},
"Interface declaration cannot contain a spread property.": {
"Spread types may only be created from object types.": {
"category": "Error",
"code": 2698
},
"Type literals with spreads cannot contain index, call or construct signatures.": {
"category": "Error",
"code": 2699
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",

View File

@ -76,8 +76,6 @@ namespace ts {
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
case SyntaxKind.SpreadElementExpression:
return visitNode(cbNode, (<SpreadElementExpression>node).expression);
case SyntaxKind.SpreadTypeElement:
return visitNode(cbNode, (node as SpreadTypeElement).type);
case SyntaxKind.Parameter:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
@ -2346,10 +2344,6 @@ namespace ts {
if (token() === SyntaxKind.OpenBracketToken) {
return true;
}
// spread elements are type members
if (token() === SyntaxKind.DotDotDotToken) {
return true;
}
// Try to get the first property-like token following all modifiers
if (isLiteralPropertyName()) {
idToken = token();
@ -2375,9 +2369,6 @@ namespace ts {
if (token() === SyntaxKind.NewKeyword && lookAhead(isStartOfConstructSignature)) {
return parseSignatureMember(SyntaxKind.ConstructSignature);
}
if (token() === SyntaxKind.DotDotDotToken) {
return parseSpreadTypeElement();
}
const fullStart = getNodePos();
const modifiers = parseModifiers();
if (isIndexSignature()) {
@ -2386,14 +2377,6 @@ namespace ts {
return parsePropertyOrMethodSignature(fullStart, modifiers);
}
function parseSpreadTypeElement() {
const element = createNode(SyntaxKind.SpreadTypeElement, scanner.getStartPos()) as SpreadTypeElement;
parseTokenNode<Node>(); // parse `...`
element.type = parseType();
parseTypeMemberSemicolon();
return finishNode(element);
}
function isStartOfConstructSignature() {
nextToken();
return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken;

View File

@ -321,8 +321,6 @@ namespace ts {
PropertyAssignment,
ShorthandPropertyAssignment,
SpreadElementExpression,
SpreadTypeElement,
// Enum
EnumMember,
@ -664,11 +662,6 @@ namespace ts {
initializer?: Expression; // Optional initializer
}
// @kind(SyntaxKind.SpreadTypeElement)
export interface SpreadTypeElement extends TypeElement {
type: TypeNode;
}
// @kind(SyntaxKind.PropertyDeclaration)
export interface PropertyDeclaration extends ClassElement {
kind: SyntaxKind.PropertyDeclaration;
@ -2521,7 +2514,7 @@ namespace ts {
Merged = 0x02000000, // Merged symbol (created during program binding)
Transient = 0x04000000, // Transient symbol (created during type check)
Prototype = 0x08000000, // Prototype property (no source representation)
SyntheticProperty = 0x10000000, // Property in union, intersection or spread type
SyntheticProperty = 0x10000000, // Property in union or intersection type
Optional = 0x20000000, // Optional property
ExportStar = 0x40000000, // Export * declaration
@ -2711,7 +2704,6 @@ namespace ts {
ContainsObjectLiteral = 1 << 22, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
Spread = 1 << 24, // Spread types
/* @internal */
Nullable = Undefined | Null,
@ -2729,12 +2721,12 @@ namespace ts {
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection | Spread,
StructuredType = Object | Union | Intersection,
StructuredOrTypeParameter = StructuredType | TypeParameter,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol | Spread,
Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol,
NotUnionOrUnit = Any | ESSymbol | Object,
/* @internal */
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
@ -2849,12 +2841,6 @@ namespace ts {
export type StructuredType = ObjectType | UnionType | IntersectionType;
/* @internal */
export interface SpreadType extends Type {
left: SpreadType | ResolvedType;
right: TypeParameter | IntersectionType | IndexType | IndexedAccessType | ResolvedType;
}
/* @internal */
// An instantiated anonymous type has a target and a mapper
export interface AnonymousType extends ObjectType {
@ -2868,7 +2854,7 @@ namespace ts {
}
/* @internal */
// Resolved object, spread, union, or intersection type
// Resolved object, union, or intersection type
export interface ResolvedType extends ObjectType, UnionOrIntersectionType {
members: SymbolTable; // Properties by name
properties: Symbol[]; // Properties

View File

@ -278,7 +278,7 @@ interface ObjectConstructor {
* @param target The target object to copy to.
* @param source The source object from which to copy properties.
*/
assign<T, U>(target: T, source: U): { ...T, ...U };
assign<T, U>(target: T, source: U): T & U;
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
@ -287,7 +287,7 @@ interface ObjectConstructor {
* @param source1 The first source object from which to copy properties.
* @param source2 The second source object from which to copy properties.
*/
assign<T, U, V>(target: T, source1: U, source2: V): { ...T, ...U, ...V };
assign<T, U, V>(target: T, source1: U, source2: V): T & U & V;
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
@ -297,7 +297,7 @@ interface ObjectConstructor {
* @param source2 The second source object from which to copy properties.
* @param source3 The third source object from which to copy properties.
*/
assign<T, U, V, W>(target: T, source1: U, source2: V, source3: W): { ...T, ...U, ...V, ...W };
assign<T, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a