简体   繁体   English

TypeChecker API:如何找到推断类型 arguments 到 function?

[英]TypeChecker API: How do I find inferred type arguments to a function?

Is there any way to, given a CallExpression with inferred type arguments, find what those type arguments are?有没有办法,给定一个推断类型为 arguments 的 CallExpression,找到那些类型 arguments 是什么?

Example code:示例代码:

class SomeClass {
    public someMethod<T>(arg: T): void { }
}

// What is the inferred type of T in this call?
someClass.someMethod(7);

It's easy enough to find type arguments that were explicitly assigned in the code, but I can't figure out how to find what was inferred.很容易找到在代码中明确分配的类型 arguments,但我无法弄清楚如何找到推断出的内容。

function inferTypeArguments(node: ts.CallExpression, typeChecker: ts.TypeChecker) {
    node.typeArguments; // is empty
    const signature = typeChecker.getResolvedSignature(node);
    signature['typeArguments']; // is also empty

    // This returns "<number>(arg: number): void"
    // so I know that the typeChecker has the right information,
    // but I would really like a ts.Type[]
    typeChecker.signatureToString(signature, node, ts.TypeFormatFlags.WriteTypeArgumentsOfSignature)
}

I'll leave this question open in case someone finds a better way, but I did accomplish this by using some internal members of "Signature".如果有人找到更好的方法,我会保留这个问题,但我确实通过使用“签名”的一些内部成员来实现这一点。

type TypeMapper = (t: ts.TypeParameter) => ts.Type;
function inferTypeArguments(node: ts.CallExpression, typeChecker: ts.TypeChecker): ts.Type[] {
  const signature = typeChecker.getResolvedSignature(node);
  const targetParams: ts.TypeParameter[] = signature['target'] && signature['target'].typeParameters;
  if (!targetParams) {
    return [];
  }
  const mapper: TypeMapper = signature['mapper'];
  return mapper
    ? targetParams.map(p => mapper(p))
    : targetParams;
}

I'd been using Simon's code for a while in my transpiler... then 3.9 came along and broke it.我在我的转译器中使用 Simon 的代码已经有一段时间了……然后 3.9 出现并破坏了它。 I've done a preliminary attempt to get it working again.我已经做了初步尝试让它再次工作。 Unfortunately, the mapper is an "internal" concern for typescript, so this will likely change again in the future不幸的是,映射器是打字稿的“内部”问题,因此将来可能会再次发生变化

/* @internal - from typescript 3.9 codebase*/
const enum TypeMapKind {
  Simple,
  Array,
  Function,
  Composite,
  Merged,
}

/* @internal - from typescript 3.9 codebase*/
type TypeMapper =
  | { kind: TypeMapKind.Simple, source: ts.Type, target: ts.Type }
  | { kind: TypeMapKind.Array, sources: readonly ts.Type[], targets: readonly ts.Type[] | undefined }
  | { kind: TypeMapKind.Function, func: (t: ts.Type) => ts.Type }
  | { kind: TypeMapKind.Composite | TypeMapKind.Merged, mapper1: TypeMapper, mapper2: TypeMapper };

/* basic application of the mapper - recursive for composite.*/ 
function typeMapper(mapper:TypeMapper, source: ts.Type): ts.Type {
  switch(mapper.kind){
    case TypeMapKind.Simple: 
      return mapper.target;
    case TypeMapKind.Array:
      throw Error("not implemented");
    case TypeMapKind.Function: 
      return mapper.func(source);      
    case TypeMapKind.Composite: 
    case TypeMapKind.Merged:
      return typeMapper(mapper.mapper2, source);
  }
}

function inferTypeArguments(node: ts.CallExpression, typeChecker: ts.TypeChecker): ts.Type[] {
  const signature:ts.Signature = typeChecker.getResolvedSignature(node);
  const targetParams: ts.TypeParameter[] = signature['target'] && signature['target'].typeParameters;

  if (!targetParams) {
    return [];
  }

  if(signature['mapper'] == undefined)   
    return targetParams;   

  //typescript <= 3.8
  if(typeof signature['mapper'] == "function") 
    return targetParams.map(p=>signature['mapper'](p));
  //typescript >= 3.9.... 
  return targetParams.map(p=> typeMapper(signature['mapper'] as TypeMapper, p));
} 

Actually now it is '4.9.4', the latest ' getMappedType ' is so complicated that I just give up implement it by myself其实现在是'4.9.4',最新的' getMappedType '太复杂了,我放弃了自己实现

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何键入函数的 arguments 但保留返回类型“推断”? - How do I type a function's arguments but leave the return type "inferred"? 如何创建一个泛型 typescript 类型 function 并从参数类型推断出返回类型? - How do I make a generic typescript type function that has the return type inferred from the argument type? 从 TypeScript 调用 JavaScript function 时,如何覆盖推断类型? - When calling a JavaScript function from TypeScript, how do I override the inferred type? 你如何使用 Typescript 编译器的 Typechecker 来获取声明的(别名)类型,而不是解析的类型? - How do you use the Typescript compiler's Typechecker to get the declared (alias) type, rather than the resolved type? 从 TypeScript 编译器 API 获取推断类型 arguments - Get inferred type arguments from TypeScript compiler API 在类型为联合的函数中未正确推断参数和返回类型 - Arguments and return type not inferred properly in function typed as union 在TypeScript中,如何键入函数的参数而不是返回值? - In TypeScript, how do i type a function's arguments but not the return value? 如何使用接口键入 function arguments? - How do I use an interface to type function arguments? 将联合类型参数传递给 function 时,如何键入接收函数的 arguments? - When passing a union type argument to a function, how do I type the receiving function's arguments? 我如何让 typescript 根据 function2E977777777777777777777777777777777777777777777777777777777777777777777777777777777777BED18 的返回类型 functionC17A94F14Z 的返回类型来推断 function 的返回类型 - How do I get typescript to infer the return type of a function based on the return type on a function of its arguments
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM