TypeScript ``` [编译器API] 函数,用于检查一个类是否实现了接口 ```

eqzww0vc  于 8个月前  发布在  TypeScript
关注(0)|答案(3)|浏览(141)

搜索词

编译器API, InterfaceDeclaration, ClassDeclaration, Checker

建议

一个函数,用于检查 ClassDeclaration 是否实现了 InterfaceDeclaration

用例

你好,我想使用编译器API检查 a.ts 文件中的 ClassDeclaration 是否实现了 b.ts 文件中的 InterfaceDeclaration。但是我找不到这样的方法或函数。

示例

  1. function isClassImplementInterface(
  2. ts.ClassDeclaration: classDeclaration,
  3. ts.InterfaceDeclaration: interfaceDeclaration
  4. ): boolean {
  5. // return true if classDeclaration implements interfaceDeclaration correctly
  6. }

检查清单

我的建议满足以下准则:

  • 这不会对现有的TypeScript/JavaScript代码造成破坏性改变
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不根据表达式的类型生成不同的JS的情况下实现
  • 这不是一个运行时特性(例如库功能、带有JavaScript输出的非ECMAScript语法等)
  • 这个特性会与 TypeScript's Design Goals 的其他部分保持一致。
kqhtkvqz

kqhtkvqz1#

我认为这不应该成为公共API的一部分。API的表面积越大,TS团队需要维护的工作就越多。
当前的API提供了编写自己的实用函数所需的一切(未经测试,但应该可以工作):

  1. function classImplementsInterface(classDeclaration: ts.ClassDeclaration, interfaceDeclaration: ts.InterfaceDeclaration, checker: ts.TypeChecker) {
  2. const heritageClause = classDeclaration.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ImplementsKeyword);
  3. if (!heritageClause) {
  4. return false;
  5. }
  6. const interfaceSymbol = checker.getSymbolAtLocation(interfaceDeclaration.name);
  7. if (!interfaceSymbol) {
  8. return false;
  9. }
  10. return heritageClause.types.some((baseType) => {
  11. let symbol = checker.getSymbolAtLocation(baseType);
  12. if (symbol && symbol.flags & ts.SymbolFlags.Alias) {
  13. symbol = checker.getAliasedSymbol(symbol);
  14. }
  15. return symbol === interfaceSymbol;
  16. });
  17. }

如果您需要了解它的作用,请在这里提问。
如果我需要这样的功能,我通常会将其放入我的实用程序库tsutils中,该库已经包含了许多有用(且大部分未记录)的函数。

展开查看全部
bvjveswy

bvjveswy2#

哇,非常感谢!上述代码将对我有很大帮助。
我会尝试根据您的指导编写一个实用程序代码。
谢谢!:D

wyyhbhjk

wyyhbhjk3#

@ajafff 我测试了上面的代码,它运行良好,但我修复了一个部分。
getSymbolAtLocation(baseType)getSymbolAtLocation(baseType.expression)

  1. function classImplementsInterface(classDeclaration: ts.ClassDeclaration, interfaceDeclaration: ts.InterfaceDeclaration, checker: ts.TypeChecker) {
  2. const heritageClause = classDeclaration.heritageClauses?.find((clause) => clause.token === ts.SyntaxKind.ImplementsKeyword);
  3. if (!heritageClause) {
  4. return false;
  5. }
  6. const interfaceSymbol = checker.getSymbolAtLocation(interfaceDeclaration.name);
  7. if (!interfaceSymbol) {
  8. return false;
  9. }
  10. return heritageClause.types.some((baseType) => {
  11. let symbol = checker.getSymbolAtLocation(baseType.expression);
  12. if (symbol && symbol.flags & ts.SymbolFlags.Alias) {
  13. symbol = checker.getAliasedSymbol(symbol);
  14. }
  15. return symbol === interfaceSymbol;
  16. });
  17. }

希望我做对了:D
谢谢!

展开查看全部

相关问题