Skip to content

Commit 126260b

Browse files
author
Kanchalai Tanglertsampan
committed
Update get attributes symbol arrays and report an error when spreading in generic
1 parent 98062a9 commit 126260b

File tree

2 files changed

+19
-17
lines changed

2 files changed

+19
-17
lines changed

src/compiler/checker.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11102,7 +11102,7 @@ namespace ts {
1110211102
function getJsxAttributesSymbolArrayFromAttributesProperty(openingLikeElement: JsxOpeningLikeElement): Symbol[] | undefined {
1110311103
const attributes = openingLikeElement.attributes;
1110411104
let attributesTable = createMap<Symbol>();
11105-
const spreads: Type[] = [];
11105+
let spread: Type = emptyObjectType
1110611106
let attributesArray: Symbol[] = [];
1110711107
for (const attributeDecl of attributes.properties) {
1110811108
const member = attributeDecl.symbol;
@@ -11130,27 +11130,28 @@ namespace ts {
1113011130
else {
1113111131
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
1113211132
if (attributesArray.length > 0) {
11133-
spreads.push(createJsxAttributesType(attributes, attributesTable));
11133+
spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), attributes.symbol);
1113411134
attributesArray = [];
1113511135
attributesTable = createMap<Symbol>();
1113611136
}
1113711137
const exprType = checkExpression(attributeDecl.expression);
11138+
if (!(getWidenedType(exprType).flags & (TypeFlags.Object | TypeFlags.Any))) {
11139+
error(attributeDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
11140+
return undefined;
11141+
}
1113811142
if (isTypeAny(getWidenedType(exprType))) {
1113911143
return undefined;
1114011144
}
11141-
spreads.push(exprType);
11145+
spread = getSpreadType(spread, exprType, attributes.symbol);
1114211146
}
1114311147
}
1114411148

11145-
if (spreads.length > 0) {
11149+
if (spread !== emptyObjectType) {
1114611150
if (attributesArray.length > 0) {
11147-
spreads.push(createJsxAttributesType(attributes, attributesTable));
11151+
spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), attributes.symbol);
1114811152
attributesArray = [];
1114911153
attributesTable = createMap<Symbol>();
1115011154
}
11151-
const propagatedFlags = getPropagatingFlagsOfTypes(spreads, /*excludeKinds*/ TypeFlags.Nullable);
11152-
const spread = getSpreadType(spreads, attributes.symbol);
11153-
spread.flags |= propagatedFlags;
1115411155
attributesArray = getPropertiesOfType(spread);
1115511156
}
1115611157

@@ -11159,13 +11160,14 @@ namespace ts {
1115911160

1116011161
/**
1116111162
* Create anonymous type from given attributes symbol table.
11162-
* @param jsxAttributes a JsxAttributes node containing attributes in attributesTable
11163+
* @param jsxAttributesSymb a JsxAttributes node containing attributes in attributesTable
1116311164
* @param attributesTable a symbol table of attributes property
1116411165
*/
11165-
function createJsxAttributesType(jsxAttributes: JsxAttributes, attributesTable: Map<Symbol>) {
11166-
const result = createAnonymousType(jsxAttributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
11166+
function createJsxAttributesType(jsxAttributesSymb: Symbol, attributesTable: Map<Symbol>) {
11167+
const result = createAnonymousType(jsxAttributesSymb, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
1116711168
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshLiteral;
11168-
result.flags |= TypeFlags.JsxAttributes | TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag;
11169+
result.flags |= TypeFlags.JsxAttributes | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag;
11170+
result.objectFlags |= ObjectFlags.ObjectLiteral;
1116911171
return result;
1117011172
}
1117111173

@@ -11182,7 +11184,7 @@ namespace ts {
1118211184
forEach(symbolArray, (attr) => {
1118311185
symbolTable[attr.name] = attr;
1118411186
});
11185-
argAttributesType = createJsxAttributesType(node, symbolTable);
11187+
argAttributesType = createJsxAttributesType(node.symbol, symbolTable);
1118611188
}
1118711189
return argAttributesType;
1118811190
}
@@ -11219,7 +11221,7 @@ namespace ts {
1121911221
}
1122011222
});
1122111223

11222-
sourceAttributesType = createJsxAttributesType(openingLikeElement.attributes, symbolTable);
11224+
sourceAttributesType = createJsxAttributesType(openingLikeElement.attributes.symbol, symbolTable);
1122311225
}
1122411226

1122511227
// If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type.
@@ -12325,7 +12327,7 @@ namespace ts {
1232512327
* @param relation a relationship to check parameter and argument type
1232612328
* @param excludeArgument
1232712329
*/
12328-
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[]) {
12330+
function checkApplicableSignatureForJsxOpeningLikeElement(node: JsxOpeningLikeElement, signature: Signature, relation: Map<RelationComparisonResult>) {
1232912331
const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
1233012332
// Stateless function components can have maximum of three arguments: "props", "context", and "updater".
1233112333
// However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
@@ -12944,7 +12946,7 @@ namespace ts {
1294412946
}
1294512947
candidate = getSignatureInstantiation(candidate, typeArgumentTypes);
1294612948
}
12947-
if (isJsxOpeningOrSelfClosingElement && !checkApplicableSignatureForJsxOpeningLikeElement(<JsxOpeningLikeElement>node, candidate, relation, excludeArgument)) {
12949+
if (isJsxOpeningOrSelfClosingElement && !checkApplicableSignatureForJsxOpeningLikeElement(<JsxOpeningLikeElement>node, candidate, relation)) {
1294812950
break;
1294912951
}
1295012952
else if (!isJsxOpeningOrSelfClosingElement && !checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {

src/harness/harness.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ namespace Harness {
10121012
}
10131013
}
10141014

1015-
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget) {
1015+
function getSourceFile(fileName: string) {
10161016
fileName = ts.normalizePath(fileName);
10171017
const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
10181018
if (fileMap.contains(path)) {

0 commit comments

Comments
 (0)