typescript 类型转换请教

2022-08-01 22:47:41 +08:00
 wjx0912
var str = '1'
var str2:number = <number> <any> str
console.log(typeof str2) // 问题 1:为什么输出 string
str2 = 1
console.log(typeof str2)
str2 = '3' // 问题 2:为什么编译错误

ts 在编译的时候是怎么控制类型的呢
谢谢
2113 次点击
所在节点    JavaScript
9 条回复
wjx0912
2022-08-01 22:50:39 +08:00
再追加几行:
var str3:number = <number> <any> str
var num4: number = 3 + str3
console.log(num4, typeof num4) // 输出: 31 string

大佬指点下编译器行为。谢谢了
noe132
2022-08-01 23:15:45 +08:00
和 C / Java 等语言很大不同的是,ts 的编译时类型和运行时类型是完全分开的,而且 ts 的编译相对来说非常简单,只需要去掉所有类型标注就是编译几乎全过程。any 这个类型可以看作一种 opt-out ,当你不像让 ts 做检查的时候就可以用 any 。而很多其他静态类型的语言根本就不存在这样的概念,这也是因为 ts 编译的 target 是 js ,是一个动态类型的语言。

ts 的编译和 C / Java 这类语言的编译有很大的区别,ts 的编译过程可以简单看做 2 步,1 对类型做检查,2 去掉所有类型标注。

现在回答一下你的问题
1. 因为 typeof 是一个运行时执行的操作符,会根据运行时变量的类型输出结果。ts 中的类型也有 typeof 操作符,比如
const a = 1
type A = typeof a
这里的 typeof 是编译时的,得到的结果是一个 ts 的类型,和你的例子中的 typeof 虽然长得一模一样,但却是 2 个不一样的东西。

2. str2 的类型是 number ,赋值一个 '3' 相当于赋值一个 string 给 number ,当然是不允许的。

3. 即使你用 as any as number 把一个 string 类型的值赋值给了一个 number 类型的变量,但是在运行时这个变量实际持有的还是 string 。ts 的类型转换不会对值做任何操作,而只是影响类型检查的结果。所以在运行时,3 + str3 实际上是 3 + '1' ,得到的结果则是 '31'。至于为啥 结果是 '31',这属于动态类型语言的问题,具体的行为得看规范( https://262.ecma-international.org/5.1/#sec-11.6.1 ),但简单来说就是如果出现了 数字+字符 的情况,无论左侧是字符还是右侧是字符,会先把 2 个都转为字符,然后再进行字符串拼接的操作。
noe132
2022-08-01 23:19:34 +08:00
当你需要把 string 内的值转换成 number 类型时,需要使用 parseInt / parseFloat / Number 这样的方法来处理。当 string 内的字符无法被解析成 number 时,通常都会给一个特殊值 NaN (Not a Number),这个值不和任何值相等,甚至 NaN 也不等于 NaN ,判断一个值是不是 NaN 的方法是 Number.isNaN
Trim21
2022-08-01 23:23:54 +08:00
typeof 是运行时的变量类型,真正的 js 运行时并不知道你用 ts 指定的变量类型

后面那个报错是 ts 编译器的报错,实际上是可以忽略然后强行编译成 js ,并且正常运行的。
thinkershare
2022-08-01 23:55:00 +08:00
问题 1:为什么输出 string, 因为 typescript 只有编译时行为, 没有运行时行为,强制类型转换就是告诉编译器你知道的比它多, 让它信任你变量是你知道的类型, 但这并不会改变变量值的实际类型
问题 2: 为什么是编译错误, 因为 typescript 核心作用就是做类型检测和提供智能提示, 这里变量的类型是 number, 当然不应该分配一个字符串给它, 因为 number 和 string 不相容
你可以理解为 TypeScript 绝对不会修改 JavaScript 的运行时行为, 它本质上是个 Type Annotation System.
Aloento
2022-08-02 02:28:55 +08:00
ts...编译后就没有类型了
wjx0912
2022-08-02 09:08:08 +08:00
@noe132 感谢。回答的太仔细了~
wjx0912
2022-08-02 09:08:29 +08:00
@Trim21 @Aloento 谢谢
wjx0912
2022-08-02 09:09:00 +08:00
@thinkershare 这个解释的很清楚。谢谢了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/870068

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX