TypeScript 基于词法范围的类字段的代码修复拼写建议

dw1jzc5e  于 2022-10-29  发布在  TypeScript
关注(0)|答案(1)|浏览(98)

建议

  • 提出问题以单独跟踪此处开始的讨论:https://github.com/microsoft/TypeScript/pull/44648/files#r709632217,如@sandersn* 建议的那样

目前,代码修复程序对属性名称的拼写建议是基于接收器类型的。当接收器类型很宽(可能是未知的)时,可以从任何周围类中的字段收集更多正确的候选名称。这可能只适用于私有字段,在私有字段中,它们只能在类中使用,或者扩展到所有字段。

🔍检索词

拼写,建议,代码修复,类字段,私有字段

可行性检查表

我的建议符合以下准则:

  • 这不会是对现有TypeScript/JavaScript代码的重大更改
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不基于表达式的类型发出不同JS的情况下实现
  • 这不是一个运行时特性(例如,库功能、带JavaScript输出的非ECMAScript语法、JS的新语法糖等)
  • 此功能与TypeScript's Design Goals的其余部分一致。

建议

📃激励性示例

class MyClass {
  #brand;

  static isMyClass(v: object): v is MyClass {
    return #brad in v; // provide code-fix here: change 'brad' to 'brand'
  }
}

私有字段查找与传统的属性查找不同,它的作用域在类内。这提供了一个有限的、可按词法发现的候选字段名称集。

💻#用例

在下列情况下,接收者类型可能太宽而无法用于候选人名称:

问题

从这里

  • 它能在多大程度上提高真实世界的回忆率?
  • 这对精确度有多大影响?
  • 它是否应该仅适用于#privates?
  • 迭代查找会影响性能吗?(可能不会,但值得考虑一下。)
  • 当类型显式为any或unknown时,编辑器不应该首先为接收器建议一个特定的类型或缩小范围吗?
yks3o0rb

yks3o0rb1#

这最初是作为https://github.com/microsoft/TypeScript/pull/44648/files的一部分实施的,但被删除以保持PR的重点,并允许对此进行单独讨论。

function getSuggestedSymbolForNonexistentProperty(propertyName: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined {
    let props = getPropertiesOfType(containingType);
    let name: string;
    if (typeof propertyName === "string") {
        name = propertyName;
    }
    else {
        name = idText(propertyName);
        const parent = propertyName.parent;
        if (isPropertyAccessExpression(parent)) {
            props = filter(props, prop => isValidPropertyAccessForCompletions(parent, containingType, prop));
        }
    }
    const suggestion = getSpellingSuggestionForName(name, props, SymbolFlags.Value);
    if (suggestion) {
        return suggestion;
    }

    // New logic:
    if (typeof propertyName !== "string" && isPrivateIdentifier(propertyName)) {
        const privateIdentifiers: Symbol[] = [];
        forEachEnclosingClass(propertyName, (klass: ClassLikeDeclaration) => {
            forEach(klass.members, member => {
                if (isPrivateIdentifierClassElementDeclaration(member)) {
                    privateIdentifiers.push(member.symbol);
                }
            });
        });
        return getSpellingSuggestionForName(name, privateIdentifiers, SymbolFlags.Value);
    }
    return undefined;
}

相关问题