TypeScript学习记录(1)

TypeScript学习记录(1)

代码的强类型,弱类型,静态类型,动态类型,分别是什么意思?

这几个概念常被混淆,核心区别在于类型检查的时机(静态/动态)和类型之间的约束强度(强/弱)。它们描述的是不同维度,一个语言可以组合出现(如 Java:静态+强类型;Python:动态+强类型)。

静态类型 – 编译时检查类型错误,变量类型通常声明后不可变

  • 例子:Java、C、C++、Rust、Go、TypeScript(JS 的超集)
  • 特点: 提前发现类型错误,性能好,代码更“啰嗦”。

动态类型 – 运行时才检查类型,变量可以随时指向任何类型的值。

  • 例子:Python、JavaScript、Ruby、PHP、Lua
  • 特点: 灵活、简洁,但类型相关 bug 可能在运行时暴露。

强类型 – 类型转换必须显式(除非极少数安全隐式转换),不会悄悄帮你乱转。

  • 例子:Python、Java、Rust、Go、C#(默认)
  • 特点: 更安全、行为可预测,拒绝“奇怪”的隐式转换。

弱类型 – 遇到不同类型操作时,语言会自动隐式转换类型,尽量让操作“完成”而不报错。

  • 例子:JavaScript、PHP、Perl
  • 特点: 写起来快,但容易产生隐晦的 bug。
interface IDemo { //这个约束就是方法的意思
  (): void;
}

let demo: IDemo = function () {
  console.log("hello world");
};
demo();
    

清除编译结果:tsc --build --clean

ts中的权限:public(不写相当于public)/protected(被保护的,只有子类才能访问)/private(只有这个类才能访问)

空值合并运算符:??, 该语法中,当且仅当“??”运算符左侧操作数a的值为undefined或null时,返回右侧操作数b;否则,返回左侧操作数a。空值合并运算符与可选链运算符一样都具有短路求值的特性。当空值合并运算符左侧操作数的值不为undefined和null时,右侧操作数不会被求值,而是直接返回左侧操作数。

TypeScript的类型系统:类型用来为程序中的实体,如函数、变量以及对象属性等添加静态的约束。

ts提供两种静态类型检查模式,非严格模式(默认)和严格模式。

非严格类型检查是TypeScript默认的类型检查模式。在该模式下,类型检查的规则相对宽松。例如,在非严格类型检查模式下不会对undefined值和null值做过多限制,允许将undefined值和null值赋值给string类型的变量。当进行JavaScript代码到TypeScript代码的迁移工作时,非严格类型检查是一个不错的选择,因为它能够让我们快速地完成迁移工作。

在严格类型检查模式下不允许将undefined值和null值赋值给string类型的变量。启用严格类型检查模式能够最大限度地利用TypeScript静态类型检查带来的益处。

ts的原始类型:undefined, null, symbol, string, number, boolean, bigint, void, 枚举,字面量。

关于symbol: symbol类型不同于其他原始类型,它不存在字面量形式。symbol类型的值只能通过“Symbol()”和“Symbol.for()”函数来创建或直接引用某个“Well-Known Symbol”值。为了能够将一个Symbol值视作表示固定值的字面量,TypeScript引入了“unique symbol”类型。

“unique symbol”类型的主要用途是用作接口、类等类型中的可计算属性名。TypeScript中只允许使用const声明或readonly属性声明来定义“unique symbol”类型的值。而且unique symbol只允许使用Symbol()和Symbol.for()来声明,不允许将其他symbol值赋给待声明变量。

上图的代码会报错,a和b类型不同。

unique symbol可以看做symbol的子类型,因此可以将unique symbol 赋给symbol.

如果程序中未使用类型注解来明确定义是symbol类型还是“unique symbol”类型,那么TypeScript会自动地推断类型。

在默认情况下,“–strictNullChecks”编译选项没有被启用。这时候,除尾端类型(never)外的所有类型都是Nullable类型。也就是说,除尾端类型外所有类型都能够接受undefined值和null值。当启用了“–strictNullChecks”编译选项时,undefined值和null值不再能够赋值给不相关的类型。例如,undefined值和null值不允许赋值给string类型。在该模式下,undefined值只能够赋值给undefined类型;同理,null值也只能赋值给null类型。[这个说法是模糊的,在该模式下,undefined/null可以赋给顶端类型(any, unknown),undefined也可以赋给void类型]

void: 除了将void类型作为函数返回值类型外,在其他地方使用void类型是无意义的。启用了strictNullChecks编译选项之后,只有undefined允许赋给void;没有启用时,undefined和null都允许赋给void.

枚举:分为数值型枚举,字符串枚举,异构型枚举。

数值型枚举是number的子类型(可以将数值型枚举赋给number变量),由一组命名的数值常量构成。

enum Direction {
  Up,
  Down,
  Left,
  Right,
}
const d: Direction = Direction.Up;
console.log(d); //0
const d1: Direction = 0;
const d2: Direction = 10; //编译报错

在定义数值型枚举时,可以为一个或多个枚举成员设置初始值。对于未指定初始值的枚举成员,其值为前一个枚举成员的值加1。

字符串枚举:字符串枚举成员必须使用字符串字面量或另一个字符串枚举成员来初始化。字符串枚举成员没有自增长的行为。字符串枚举是string的子类型,可以把枚举赋值给string变量,反过来不行。

enum Direction1 {
  Up = "Up",
  Down = "Down",
  Left = "Left",
  Right = "Right",
}
const d2: Direction1 = Direction1.Up;
console.log(d2); //"Up"

异构型枚举:在一个枚举中同时定义数值型枚举成员和字符串枚举成员,不推荐使用。

enum ColorA {
  Black, //没问题
  White = "White" 
}

enum ColorB {
  Black = "Black",
  White //报错:跟在字符型枚举值后面的数值枚举值必须指定值
}

若枚举成员的初始值是常量枚举表达式,那么该枚举成员是常量枚举成员。常量枚举表达式是TypeScript表达式的子集,它能够在编译阶段被求值。

常量枚举表达式的规则是:

  • 常量枚举表达式可以是数字字面量、字符串字面量和不包含替换值的模板字面量。
  • 常量枚举表达式可以是对前面定义的常量枚举成员的引用。
  • 常量枚举表达式可以是用分组运算符包围起来的常量枚举表达式。
  • 常量枚举表达式中可以使用一元运算符+/-/~操作数必须为常量枚举表达式。
  • 常量枚举表达式中可以使用二元运算符+/-/*/**/%/\//<</>>/&/|/^,两个操作数必须为常量枚举表达式。

字面量枚举成员又是常量枚举成员的子集,它的规则是:

  • 枚举成员没有定义初始值
  • 初始值为是数字字面量、字符串字面量和不包含替换值的模板字面量
  • 枚举成员的初始值为对其他字面量枚举成员的引用

除常量枚举成员之外的其它枚举成员都是计算枚举成员

当枚举类型中的所有成员都是字面量枚举成员时,这个枚举类型叫做联合枚举类型。联合枚举类型是由所有联合枚举成员类型构成的联合类型。

发表回复

*您的电子邮件地址不会被公开。必填项已标记为 。

*
*