1
wjx0912 OP 再追加几行:
var str3:number = <number> <any> str var num4: number = 3 + str3 console.log(num4, typeof num4) // 输出: 31 string 大佬指点下编译器行为。谢谢了 |
2
noe132 2022-08-01 23:15:45 +08:00 1
和 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 个都转为字符,然后再进行字符串拼接的操作。 |
3
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
|
4
Trim21 2022-08-01 23:23:54 +08:00 via Android
typeof 是运行时的变量类型,真正的 js 运行时并不知道你用 ts 指定的变量类型
后面那个报错是 ts 编译器的报错,实际上是可以忽略然后强行编译成 js ,并且正常运行的。 |
5
thinkershare 2022-08-01 23:55:00 +08:00
问题 1:为什么输出 string, 因为 typescript 只有编译时行为, 没有运行时行为,强制类型转换就是告诉编译器你知道的比它多, 让它信任你变量是你知道的类型, 但这并不会改变变量值的实际类型
问题 2: 为什么是编译错误, 因为 typescript 核心作用就是做类型检测和提供智能提示, 这里变量的类型是 number, 当然不应该分配一个字符串给它, 因为 number 和 string 不相容 你可以理解为 TypeScript 绝对不会修改 JavaScript 的运行时行为, 它本质上是个 Type Annotation System. |
6
Aloento 2022-08-02 02:28:55 +08:00 1
ts...编译后就没有类型了
|
9
wjx0912 OP @thinkershare 这个解释的很清楚。谢谢了
|