获取变量的 TypeScript 类型

huangapple go评论72阅读模式
英文:

Get the TypeScript type of a variable

问题

Is there an expression that evaluates to the type that TypeScript believes a values inhabits?

我一直在尝试搜索,但所有的答案都涉及到JavaScript的运行时类型,而不是TypeScript的类型。

例如

const a = 5 as unknown as string;
console.log(typeof a);
// number

上面的打印结果是"number",因为它从JavaScript的运行时获取了类型。然而,TypeScript却认为a是一个字符串。以下的类型检查通过,因为TypeScript认为a是一个字符串:

function naiveType(v: string): string {
  return "string";
}

const a = 5 as unknown as string;
console.log(naiveType(a));
英文:

Is there an expression that evaluates to the type that TypeScript believes a values inhabits?


I've been trying to search, but all the answers are about Javascript's runtime types and not TypeScript's types.

For example

const a = 5 as unknown as string;
console.log(typeof a);
// number

The above print "number" because it's getting a type from JavaScript at runtime. Typescript, however, assumes that a is a String. The following type checks because TypeScript believes a is a String:

function naiveType(v: string): string {
  return "string";
}

const a = 5 as unknown as string;
console.log(naiveType(a));

答案1

得分: 1

这是不可能的,使用TypeScript编译器无法实现。

TypeScript的一个设计非目标之一是,TypeScript不会:

  1. 在程序中添加或依赖运行时类型信息,或根据类型系统的结果生成不同的代码。相反,鼓励不需要运行时元数据的编程模式。

如果有一个名为tsTypeof的操作符以您希望的方式运作,TypeScript代码

const a = 5 as unknown as string;
console.log(tsTypeof a);

需要编译为类似以下的JavaScript代码

const a = 5;
console.log("string");

而TypeScript代码

const a = 5 as unknown as number;
console.log(tsTypeof a);

需要编译为类似以下的代码

const a = 5;
console.log("number");

这意味着tsTypeof a会根据类型系统的结果编译为不同的内容,违反了这一规则。

如果有人提出创建这种操作符的功能请求,几乎肯定会被拒绝,因为无法如实勾选TypseScript功能请求问题模板中的复选框:

☑ 可以在不基于表达式类型发出不同JS的情况下实现这个。

如果您想要类似的功能,您需要添加一个构建步骤,使用例如TypeScript编译器API来处理您的TypeScript代码,并将其转换为保留编译时类型信息的形式。肯定存在已有的框架可以为您执行此操作,比如Deepkit的typeOf()函数。但这会将我们带出纯TypeScript的范畴,进入外部工具的领域,这不是这个问题的重点。

英文:

For better or worse this is not possible with the TypeScript compiler.


One of TypeScript's Design Non-Goals is that TypeScript would:

> 5. Add or rely on run-time type information in programs, or emit different code based on the results of the type system. Instead, encourage programming patterns that do not require run-time metadata.

If there were a tsTypeof operator that acted the way you want, the TypeScript code

// TS
const a = 5 as unknown as string;
console.log(tsTypeof a);

would need to compile to something like the following JavaScript

// JS
const a = 5;
console.log("string");

while the TypeScript code

// TS
const a = 5 as unknown as number;
console.log(tsTypeof a);

would need to compile to something like

// JS
const a = 5;
console.log("number");

which means that tsTypeof a would compile to different things depending on the results of the type system, which violates the rule.


If someone were to open a feature request for such an operator, it would almost certainly be declined, since one couldn't truthfully check the box in the TypseScript feature request issue template that says

> ☑ This could be implemented without emitting different JS based on the types of the expressions.


If you want something like this, you'd need to add a build step that used, say, the TypeScript compiler API to process your TypeScript code and convert it to a form that preserves the compile-time type information. There are certainly existing frameworks that do this for you, such as Deepkit's typeOf() function. But this takes us outside the realm of pure TypeScript and into external tools, which isn't the focus of this question.

huangapple
  • 本文由 发表于 2023年2月24日 03:43:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75549608.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定