1,强类型和弱类型(类型安全)
强类型:在语言层面,函数的实参类型必须与形参类型相同;
弱类型:在语言层面不会限制实参的类型;
强类型有更强的类型约束,而弱类型几乎没有任何约束;
强类型语言中不允许任意的隐式类型转换,而弱类型语言中允许任意的隐式类型转换;
变量类型允许随时改变的特点,不是强弱类型的差异;
2,静态类型和动态类型(类型检查)
静态类型:一个变量在声明时它的类型就是明确的,声明过后,它的类型不允许再改变;
动态类型:在允许阶段才能明确变量的类型,而且变量的类型可以随时改变;
3,typeScript
typeScript
是javascript
的超集;
安装:yarn add typescript --save-dev
编译:yarn tsc index.ts
配置文件:运行yarn tsc --init
会自动生成tsconfig.json
配置文件,文件中包含所有的配置信息,配置好配置文件再运行yarn tsc
就会对整个项目进行编译。
标准库就是内置对象所对应得声明;
4,声明基础类型
let str:string = 'xxx';//声明字符串
let a:number = 2;//声明数字
let b:boolean = true;//声明boolean类型
let u:undefined = undefined;//声明undefined
let n:null = null;//声明null
let c:any = 12;//声明any类型,类型可以随意改变
void
:void
类型像是与any
类型相反,它表示没有任何类型。当一个函数没有返回值时,通常使用void
表示:
function func():void{console.log(0)};
5,Object类型
object
类型并不单指对象,而是原始类型以外的其它类型;对象的限制,可以使用类似对象字面量的方式,但更专业的方式是使用接口;
const foo:object = function(){} | [] | {};
如果需要限制对象类型,则应该使用这种类型对象字面量的语法,或者使用接口:
const foo:{a:string,b:number} = {a:'a',b:1};
6,数组类型
数组有两种形式:
const arr:Array<number> = [1,2,3];
const temp:number[] = [1,2,3];
7,元组类型
元组就是一个明确元素数量以及每个元素类型的数组:
const arr:[string,number] = ['abc',123];
8,枚举类型
标准的数字枚举,枚举值自动基于前一个值自增; 默认从0开始
enum postdata {
first,//0
secont,//1
sret,//2
}
也可以自定义开始的值:
enum postdata {
first = 5,
secont,//6
sret,//7
}
常量枚举,不会侵入编译结果:
const enum postData {
first,
secont,
sret,
}
9,函数类型
函数中如果某一个参数是非必填的,则在参数后面加一个?
表示:b?:number
;
function func(a:number,b?:number):string{ return 'func'}
func(123,234);
func(123);
10,隐式类型推断
在没有给变量设置类型时,typescript
会进行隐式类型推断,可能会引起不必要的错误,建议给每个变量设置类型;
11,类型断言
在某些情况下typescript
不能准确判断变量的类型,比如:
//假设这个arr来自于一个明确的接口
const arr = [123,456,789];
const result = arr.find((v) => v > 0);//在这里typescript推断result是number或者undefined;
const squery = result * result;//在这里使用乘法时就会报错;
类型断言,就是明确告诉typescript
result
一定是number
;
const num1 = result as number
或者
const num2 = <number>result;// JSX 下不能使用
12,接口
接口是为了约束对象的结构,只是为对象属性进行类型约束;
interface Post {
title:string,
count:string
}
function func(post:Post){ ... };
func({
title:'javascript',
count:'lean'
})
可选成员,在属性后面加一个问号,就表示该属性可以有也可以没有:
interface Post{
title:string,
count:string,
auth?:string
}
只读成员,在属性名称前面加上readonly
修饰符,就表示该属性设置值之后就不可以再修改:
interface Post {
readonly title:string
}
let post:Post = {title:'javascript'};
post.title = 'vue';//报错,title是只读属性,不可更改;
动态成员,对象的属性名是不确定的,会动态修改:
interface Post {
[key:string]:string
}
13,类
类:描述一类具体事物的抽象特征;typescript
中类的属性必须要提前声明;
class Person {
name:string;
constructor(name:string){
this.name = name;
}
}
类的访问修饰符:public
:公有属性,能在实例中访问;private
:私有属性,不能在实例中访问;protected
:私有属性,可以被继承,不能在实例中访问;
class Person {
public name:string;
private age:number;
protected gender:boolean;
}
类的只读属性:readonly
,跟在访问修饰符之后:
class Person {
public name:string;
private age:number;
protected readonly gender:boolean;
}
类与接口:implements
interface Eat{
eat (food:string) :void;
}
interface Run{
run (step:number) :void;
}
class Person implements Eat,Run {
eat (food: string): void {
console.log(`优雅的进餐: ${food}`)
}
run (distance: number) {
console.log(`直立行走: ${distance}`)
}
}
抽象类:只能被继承,不能创建实例,abstract
;
abstract class Animal {
eat (food: string): void {
console.log(`呼噜呼噜的吃: ${food}`)
}
abstract run (distance: number): void
}
class Dog extends Animal {
run(distance: number): void {
console.log('四脚爬行', distance)
}
}
const d = new Dog()
d.eat('嗯西马')
d.run(100)
14,泛型
泛型:就是在定义接口或者类的时候不去指定参数类型,等到使用的时候再去指定类型的特征;
function creatArr<T>(lean:number,value:T):T[]{
const arr = Array<T>(lean).file(value);
return arr;
}
const res = creatArr<string>(2,'foo');
15,类型声明
对应没有使用typescript
写的npm
包,要么下载它的类型声明包,或者使用declare
语句自己确定类型声明;
import { camelCase } from 'lodash';
declare function camelCase (input:string):string;
const res = camslCase('hello typescript');