女友御用版TS解析
优势:
-增加了代码的可阅读和可维护性
安装:
npm install -g typescript
一.基础类型
布尔值
let isDone: boolean = false;
数字 number
let number: number = 6;
let notANumber: number = NaN;
字符串
let string: string = 'Tom';
空值 void
- void 类型的变量只能赋值为 undefined 和 null
let unusable: void = undefined;
- 可以用 void 表示没有任何返回值的函数
function myname():void{
}
null 和 undefined
- undefined 类型的变量只能被赋值为 undefined,null 类型的变量只能被赋值为 null
let u: undefined = undefined;
let n: null = null;
与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量:
let u: undefined;
let num: number = u;
let num2:number = undefined;
// 编译合法 undefined是number的子类型
let unm2: void;
let num3: number = unm2;
// => 不合法 (void不是number的子类型)
任意值 any
let anyType:any = 'seven';
anyType = 7;
变量如果在声明的时候,未指定其类型, 也没有赋值, 那么它会被推断(类型推论)为任意值类型而完全不被类型检查
let something;
// 等价于 let something: any;
something = 'seven';
something = 7;
二.数组
1,类型 + 方括号( type [ ] )
这种方式定义的数组项中不允许出现其他的类型
let list: number[] = [1, 2, 3];
2,数组泛型 Array < type >
let list: Array<number> = [1, 2, 3];
三.元祖
简单理解为可定义一组不同类型的数据:
let arr:[string, number] = ['name', 20];
console.log(arr[0]);
// => 'name'
越界元素:当访问超出元祖长度的元素时,它的类型会被限制为元祖中每个类型的联合类型
let arr:[string, number] = ['name', 20];
arr[0] = 'age';
arr[2] = 'string';
arr[3] = 40;
arr[4] = true; // 编译报错
四.枚举 enum
被限定在一定范围内的场景,如一周只有7天,一年只有4季等
- 数字枚举
enum Weeks {Mon, Tue, Wed, Thu, Fri, Sat, Sun};
- 字符串枚举
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
常量枚举在编译阶段是会被删除的
五.类型推论
变量申明如果没有明确的指定类型,那么 TypeScript 会依照类型推论的规则推断出一个类型
let string = 'seven';
// 等价于 let string: string = 'seven';
string = 4;
// 编译报错: error TS2322: Type 'number' is not assignable to type 'string'
变量声明但是未赋值,会推论为 any
let x;
x = 1;
x = 'aaa'
六.联合类型
let stringOrNumber:string | number;
stringOrNumber = 'seven';
七.类型断言
实则类似
instanceof
,来断定一个类型
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
八.自定义类型
// 类型别名用法 自定义自己类型 public private等
type myType = {
name: string,
age: number,
}
接口 Interfaces
必须一一对应key和value
// 定义一个接口 Person
interface Person {
name: string;
age: number;
}
// 定义一个个变量,它的类型是 Person
let tom: Person = {
name: 'Tom',
age: 25
};
可选属性
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'tom'
}
// age是可选属性
任意属性(定义之后,person03所有的value只都必须为any)
interface Person03 {
name: string;
age?: number;
[propName: string]: any;
}
let tom04: Person03 = {
name: 'Tom',
age: 25,
gender: 'male'
};
只读属性readonly(一次给对象赋值可以,但是不能修改)
interface Person {
readonly id: number;
}
let person: Person = {
id: 100,
}
person.id = 2//报错
函数
用接口定义函数的形状
interface FuncAdd {
(value: number, increment: number): number
}
let add: FuncAdd;
add = function(value: number, increment: number): number {
return value + increment;
}
// 函数的参数名不需要与接口里定义的名字相匹配
let add2: FuncAdd;
add2 = function(a: number, b: number) {
return a + b;
}
可选参数(必须放在参数的最后面)
function addNum(a: number, b: number, c? :number): number {
if(c) {
return a + b + c;
} else {
return a + b;
}
}
console.log(add(1, 2));
默认参数
function add(a: number = 1, b: number): number {
return a + b;
}
console.log(add(undefined, 1))
类 class
类的定义
class Animal {
name:string; // 定义属性
constructor(name) {
this.name = name; // 属性赋值
}
sayHi() {
return `我叫 ${this.name}`;
}
}
let cat = new Animal('Tom');
console.log(cat.sayHi()); // 我叫 Tom
类的继承
class Cat extends Animal {
color: string;
constructor(name, color) {
super(name); // 调用父类Animal的 constructor(name)
this.color = color
}
sayHi() {
// 调用父类的 sayHi();
return super.sayHi() + '我是一只'+ this.color + ' 色的猫,';
}
}
let c = new Cat('Tom', '橘黄'); // Tom
console.log(c.sayHi()); // 我叫 Tom,我是一只橘黄色的猫;
let cat2 = new Cat('Jerry');
cat2.color = '黑';
console.log(c.sayHi()); // 我叫 Jerry,我是一只黑色的猫;
存取器
class Animal {
name:string;
constructor(name) {
this.name = name;
}
get name() {
return 'Jack';
}
set name(value) {
console.log('setter: ' + value);
}
}
let a = new Animal('Kitty'); // setter: Kitty
a.name = 'Tom'; // setter: Tom
console.log(a.name); // Jack
静态属性和方法
- static--子类不继承
-public--公共方法
-private--私有
-protected--继承的子类可以访问
多态
子类同种父类的方法名字
class Person {
eat(){ console.log('eat') }
}
class A extends Person {
eat(){ console.log('A eat') }
}
class B extends Person {
eat(){ console.log('B eat') }
}
泛型函数
// 打印字符串
function printer1(arr:string[]):void {
for(var item of arr) {
console.log(item)
}
}
printer1(['a','b','c','d'])
--------------------------------------------------------------------
function printer<T>(arr:T[]):void {
for(var item of arr) {
console.log(item)
}
}
// 指定具体类型调用
printer<string>(['a','b','c','d']);
// 调用时也可以直接让ts自己做类型推论
printer([1,2,3,4]);
声明文件 declare
当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能
后续为实战,未完待续......我太难了啊
//传给函数,用来解构赋值
class a {
aa({a,b}:{a:number,b:string}):void{
console.log(11)
}
}
let b = new a()
b.aa({
a:1,
b:"1"
})
工作中用到的
//基本数据类型--------------------------------------
private str:string = ''
//数组(三种,我们用两种)
//1
private arr: string[] = ['1','2']
//2
private Array<string> = ['1','2']
//对象---------------------------
//允许接口里有任意属性。但是是所有子集的父级
//1(一般任意用了 就不写别的了)
interface test{
name: string;
age?: number;
[propName: string]: any;
}
//2
interface obj{
name: string; // 表示对象要有name属性, 值是string类型
age?: number; // ? 表示age属性可以有也可以没有, 值是number类型
readonly id: number; // readonly 表示 id 属性只可读,不可修改
}
let obj2: obj= { name: "obj2", age: 18, id: 2 };
//数组对象
interface test{
name1: string;
}
interface zz{
name: test;
}
const aaa:zz[] = [{name:{name1:"2"}}]
//函数
//1
function fn(x:number,y?: number,z:number = 1):void{}
//2