首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何计算TypeScript对象类型中使用的属性?

如何计算TypeScript对象类型中使用的属性?
EN

Stack Overflow用户
提问于 2022-07-27 16:00:20
回答 2查看 136关注 0票数 2

我正在寻找一种方法来计算在我的代码库中实际使用的对象类型的哪些部分。假设我在一个types.ts文件中有以下内容:

代码语言:javascript
复制
export type Animal = {
  id: number;
  name: string;
  height: number;
  isMammal: boolean;
}

在另一个文件中,我做了一个API调用,返回一个动物:

代码语言:javascript
复制
const getAnimal: (id: number) => Promise<Animal>

在两个单独的文件中,我调用getAnimal并使用生成的Animal

代码语言:javascript
复制
const animal1 = await getAnimal(1);
console.log(`Hi! Animal with id ${animal1.id} is named ${animal1.name}.`)
代码语言:javascript
复制
const animal1 = await getAnimal(1);
console.log(`This animal is ${animal1.height} feet tall.`)

但在我的项目中,我没有任何地方使用isMammal属性。如何编写一个脚本来扫描项目中的所有文件,并告诉我isMammal不在Animal类型上使用?或者,只有idnameheight 才是

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-04 18:59:22

要使用编译器API执行此操作,您需要通过ts.LanguageServer使用和设置一个ts.createLanguageService(...),然后使用findReferences方法,该方法返回所有使用的引用,类似于编辑器中的引用。

下面是一个完整的示例:

代码语言:javascript
复制
// setup code because doing this with the compiler API alone is a lot to show
import { createProjectSync, ts } from "https://deno.land/x/ts_morph@15.1.0/bootstrap/mod.ts";

const project = createProjectSync();
const sourceFile = project.createSourceFile("file.ts", `
export type Animal = {
  id: number;
  name: string;
  height: number;
  isMammal: boolean;
};

const animal: Animal = {} as any;
animal.id;
animal.name;
animal.height;
`);
const languageService = project.getLanguageService();

// compiler API code starts here
const animalType = sourceFile.statements[0] as ts.TypeAliasDeclaration;
const animalObjectType = animalType.type as ts.TypeLiteralNode;

for (const member of animalObjectType.members) {
  if (ts.isPropertySignature(member)) {
    const findResult = languageService.findReferences(
      sourceFile.fileName,
      member.name.getStart(sourceFile),
    );
    const references = (findResult ?? [])
      .reduce<ts.ReferencedSymbolEntry[]>((a, b) => a.concat(b.references), [])
      .filter(r => !r.isDefinition);
    if (references.length === 0) {
      console.log(member.name.getText(sourceFile));
    }
  }
}

产出:

代码语言:javascript
复制
isMammal
票数 3
EN

Stack Overflow用户

发布于 2022-08-04 07:46:43

更新:见@大卫·雪莉的回答。比我的好:)

@T.J.Crowder建议调查TypeScript编译器API。我也没有深入研究过它,但是从一个快速的角度来看,它似乎与你想要做的事情并没有太大的关系。它是TypeScript编译器的API。

我还建议查看语言服务API ( IDE集成的基础是IDEs (如VS代码)中的类型记录),这可能更接近于您想要的。有一个可执行的"tsserver“,它封装了编译器API和语言服务,可能对用户更友好。有关使用的信息,请参阅链接的wiki页面。

特别是,如果您查看引用的协议.d.ts文件,您将看到

代码语言:javascript
复制
    /**
     * Instances of this interface specify a location in a source file:
     * (file, line, character offset), where line and character offset are 1-based.
     */
    interface FileLocationRequestArgs extends FileRequestArgs {
        /**
         * The line number for the request (1-based).
         */
        line: number;
        /**
         * The character offset (on the line) for the request (1-based).
         */
        offset: number;
    }

// ...

    /**
     * A request whose arguments specify a file location (file, line, col).
     */
    interface FileLocationRequest extends FileRequest {
        arguments: FileLocationRequestArgs;
    }

// ...

    /**
     * Find references request; value of command field is
     * "references". Return response giving the file locations that
     * reference the symbol found in file at location line, col.
     */
    interface ReferencesRequest extends FileLocationRequest {
        command: CommandTypes.References;
    }

您可以使用ctrl+F "ReferencesResponse“来查找部分响应数据的接口定义。

如果您想尝试这一点,接下来的步骤将是创建一个程序,该程序使用参数指定要扫描引用的类型定义的文件位置,然后设置本地tsserver并调用它以查找对这些类型定义字段的引用,并生成项目中任何地方都未引用的字段列表。

这与完整的答案相去甚远,但公平地说,我不认为这是经常探索的领域(尽管找到未使用的变量和参数是一个解决了的问题),如果真的是这样的话,我不认为有人会来为你做你所有的工作(或者你会这么做)。我不太熟悉堆栈溢出文化)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73141186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档