Typescript特点及优势
静态输入: 静态类型化是一种功能,可以在开发人员编写脚本时检测错误。 可读性和易维护性:从JS动态弱类型检查到TS强类型检查,增加了静态类型、类、模块、接口和类型注解。 接口和类型提示使代码更具可读性。同时编译检查让项目更具易维护性。 更好的协作: 类型安全是一种在编码期间检测错误的功能,而不是在编译项目时检测错误。这为开发团队创建了一个更高效的编码和调试过程
Typescript 核心语法
1.变量语法
变量声明语法有四部分组成:变量,分隔符( : ), 类型 (number, string) 和 值(value)。

变量语法实例
let isDone: boolean = false; // 布尔类型
let decLiteral: number = 6; // 数字类型
let sentence: string = 'Hello, my name is ${ name }.'; // 字符类型
let list: number[] = [1, 2, 3]; // 数组类型
let list: Array<number> = [1, 2, 3]; // 数组泛型
let x: [string, number] = ['1', 2]; // 元组Tuple
2.函数声明语法
标准函数声明需要定义参数类型和返回类型,参数和返回类型可以是 基础数据类型 和 自定义数据类型。
函数声明语法也有四部分组成:函数名, 变量, 变量类型 (基础类型(String) 和 自定义类型(UserInfoObject) ) 和 返回类型 (void))
函数声明实例
interface GreetingSettings {
greeting: string;duration?: number;
color?: string;
}
declare function greet(setting: GreetingSettings): void;
// 双箭头函数说明
const testAbc = (abc: funAbcSign):string => {
return funcAbcSign.abc;
}
3.类
3.1 如何定义类
class Person{
name:string;
getName():void{
console.log(this.name);
}
}
let p1 = new Person();
p1.name = 'zhufeng';
p1.getName();
3.2 存取器
- 在 TypeScript 中,我们可以通过存取器来改变一个类中属性的读取和赋值行为
- 构造函数
- 主要用于初始化类的成员变量属性
- 类的对象创建时自动调用执行
- 没有返回值
class User {
myname:string; constructor(myname: string) {
this.myname = myname;
}
get name() {
return this.myname;
}
set name(value) {
this.myname = value;
}
}let user = new User('zhufeng');
user.name = 'jiagou';
console.log(user.name);
3.3 参数属性
class User {
constructor(public myname: string) {}
get name() {
return this.myname;
}
set name(value) {
this.myname = value;
}
}
let user = new User('zhufeng');console.log(user.name);
user.name = 'jiagou';
console.log(user.name);
3.4 readonly
- readonly修饰的变量只能在构造函数中初始化
- -在 TypeScript 中,const 是常量标志符,其值不能被重新分配
- TypeScript 的类型系统同样也允许将 interface、type、 class 上的属性标识为 readonly
- readonly 实际上只是在编译阶段进行代码检查。而 const 则会在运行时检查(在支持 const 语法的 JavaScript 运行时环境中)
class Animal {
public readonly name: string
constructor(name) {
this.name = name;
}
changeName(name:string){
this.name = name;
}
}
let a = new Animal('zhufeng');
a.changeName('jiagou');
- 基础数据类型数据类型主要有:string、boolean、number、Array、void、null、undefined、Tuple、enum、object、never、any。
- Tuple元组类型: 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
- any类型: 不清楚类型的变量指定一个类型,指定任意类型。
// 枚举类型
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
// tuple类型
let x: [string, number]; // Declare a tuple type
x = ['hello', 10]; // OK Initialize it
x = [10, 'hello']; // Error Initialize it incorrectly
// 空类型
let unusable: void = undefined;
// any类型
let list: any[] = [1, true, "free"]
list[1] = 100;
接口
- TypeScript的核心原则之一是对值所具有的结构进行类型检查, 它有时被称做“鸭式辨型法”或“结构性子类型化”。
- 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约, 类可以定义为接口。
// 内联接口
function printUserInfo(user: {age: number, name: string, sex?: string}): void {
console.log('user', user);
}
// 外联接口
interface UserInfoObject {
age: number,
name: string,
sex?: string
}
function printUserInfo(user: UserInfoObject): void {
console.log('user', user);
}
泛型的使用
软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
// 参数和返回值类型一样,但不确定
function getUser<T>(user: T):T {
return user;
}
// 泛型接口
interface getUserFn {
<T>(arg: T): T;
}
const getMyUser:getUserFn = getUser
泛型接口 vs 泛型类型别名
- 接口创建了一个新的名字,它可以在其他任意地方被调用。而类型别名并不创建新的名字,例如报错信息就不会使用别名
- 类型别名不能被 extends和 implements,这时我们应该尽量使用接口代替类型别名
- 当我们需要使用联合类型或者元组类型的时候,类型别名会更合适
类型保护
- 类型保护就是一些表达式,他们在编译的时候就能通过类型信息确保某个作用域内变量的类型
- 类型保护就是能够通过关键字判断出分支中的类型
typeof 类型保护
function double(input:string|number|boolean){if(typeof input === 'string'){
return input + input;
}else {
if(typeof input === 'number'){
return input*2;
}else{
return !input;
}
}
}
instanceof类型保护
class Animal{
name:string;
}
class Bird extends Animal{
swing:number
}
function getName(animal:Animal){
if(animal instanceof Bird){
console.log(animal.swing);
} else {
console.log(animal.name);
}
}
null保护
如果开启了strictNullChecks选项,那么对于可能为null的变量不能调用它上面的方法和属性
function getFirstLetter(s:string|null){ //第一种方式是加上null判断
if(s == null){
return '';
}
//第二种处理是增加一个或的处理
s = s || '';
return s.charAt(0);
}
//它并不能处理一些复杂的判断,需要加链判断运算符
function getFirstLetter2(s:string|null){
function log(){
console.log(s!.trim());
}
s = s || '';
log();
return s.charAt(0);
}