Skip to content

Commit 5853d2a

Browse files
committed
feat: re-impl react class name fix
1 parent c8abf6f commit 5853d2a

File tree

4 files changed

+17
-10
lines changed

4 files changed

+17
-10
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16322,7 +16322,7 @@ namespace ts {
1632216322
errorNode = prop.valueDeclaration.name;
1632316323
}
1632416324
const propName = symbolToString(prop);
16325-
const suggestion = getSuggestionForNonexistentProperty(propName, errorTarget);
16325+
const suggestion = getSuggestionForNonexistentProperty(propName, errorTarget, true);
1632616326
if (suggestion) reportError(Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName, typeToString(errorTarget), suggestion);
1632716327
else reportError(Diagnostics.Property_0_does_not_exist_on_type_1, propName, typeToString(errorTarget));
1632816328
}
@@ -24878,12 +24878,12 @@ namespace ts {
2487824878
return prop !== undefined && prop.valueDeclaration && hasSyntacticModifier(prop.valueDeclaration, ModifierFlags.Static);
2487924879
}
2488024880

24881-
function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined {
24882-
return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value);
24881+
function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type, isJSX = false): Symbol | undefined {
24882+
return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value, isJSX);
2488324883
}
2488424884

24885-
function getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined {
24886-
const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType);
24885+
function getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type, isJSX = false): string | undefined {
24886+
const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType, isJSX);
2488724887
return suggestion && symbolName(suggestion);
2488824888
}
2488924889

@@ -24956,8 +24956,8 @@ namespace ts {
2495624956
* (0.4 allows 1 substitution/transposition for every 5 characters,
2495724957
* and 1 insertion/deletion at 3 characters)
2495824958
*/
24959-
function getSpellingSuggestionForName(name: string, symbols: Symbol[], meaning: SymbolFlags): Symbol | undefined {
24960-
return getSpellingSuggestion(name, symbols, getCandidateName);
24959+
function getSpellingSuggestionForName(name: string, symbols: Symbol[], meaning: SymbolFlags, isJSX = false): Symbol | undefined {
24960+
return getSpellingSuggestion(name, symbols, getCandidateName, isJSX);
2496124961
function getCandidateName(candidate: Symbol) {
2496224962
const candidateName = symbolName(candidate);
2496324963
if (startsWith(candidateName, "\"")) {

src/compiler/core.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1817,14 +1817,21 @@ namespace ts {
18171817
* (0.4 allows 1 substitution/transposition for every 5 characters,
18181818
* and 1 insertion/deletion at 3 characters)
18191819
*/
1820-
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined {
1820+
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined, isJSX = false): T | undefined {
18211821
const maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
18221822
let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result isn't better than this, don't bother.
18231823
let bestCandidate: T | undefined;
18241824
let justCheckExactMatches = false;
18251825
const nameLowerCase = name.toLowerCase();
18261826
for (const candidate of candidates) {
18271827
const candidateName = getName(candidate);
1828+
if (isJSX) {
1829+
const htmlFor = name === "for" && candidateName === "htmlFor";
1830+
const className = name === "class" && candidateName === "className";
1831+
if (htmlFor || className) {
1832+
return candidate;
1833+
}
1834+
}
18281835
if (candidateName !== undefined && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference) {
18291836
const candidateNameLowerCase = candidateName.toLowerCase();
18301837
if (candidateNameLowerCase === nameLowerCase) {

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4009,7 +4009,7 @@ namespace ts {
40094009
*/
40104010
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
40114011
getApparentType(type: Type): Type;
4012-
/* @internal */ getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined;
4012+
/* @internal */ getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type, isJSX?: boolean): Symbol | undefined;
40134013
/* @internal */ getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined;
40144014
/* @internal */ getSuggestedSymbolForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): Symbol | undefined;
40154015
/* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;

src/services/codefixes/fixSpelling.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace ts.codefix {
5656
Debug.assertNode(node, isIdentifier, "Expected an identifier for JSX attribute");
5757
const tag = findAncestor(node, isJsxOpeningLikeElement)!;
5858
const props = checker.getContextualTypeForArgumentAtIndex(tag, 0);
59-
suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, props!);
59+
suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, props!, true);
6060
}
6161
else {
6262
const meaning = getMeaningFromLocation(node);

0 commit comments

Comments
 (0)