出现的主要目的:解决javascript的类型系统不足。
类型安全:
强类型 vs. 弱类型
隐式类型转换:强类型不允许,弱类型允许。
语言层面的类型检查。
类型检查:
静态类型:声明时,就确定了,不允许变更。
动态类型:运行时定义,可以动态变更类型。
目前语言分布情况
javascript类型系统特征
动态类型,弱类型-->不靠谱。
脚本语言,没有编译环节。
规模:复制程度-->越来越复杂(没有类型,开发维护越来越吃力)。
弱类型的问题:
君子约定存在隐患,强制要求有保障。
强类型的优势:
类型注解:
增加类型注解的方式。
// @flow
function sum(a:number,b:number):number{
return a+b;
}
a:number类型注解(需要的地方增加);
Flow小工具,so easy!中间加入了编译的小环节。
通过Flow可以检查代码中的类型问题。
运行阶段:移除类型注解。
开发工具插件:
vscode+Flow Language Support:直接再开发工具中显示,保存后提示。
类型推断:
根据代码的使用情况,推断变量类型。
原始类型:
//@flow
//基本类型
let a:string="123";
let b:number=NaN;//包含NaN,Infinity
let c:boolean=true;
let d:null=null;
let e:void=undefined;
let f:symbol=Symbol();
//数组
let arr:Array=[1,2];
let arr:number[]=[1,2];
//元组
let arr[string, number]=["test", 100];
//对象
let obj1:{name:string,arge:number}={"name":"shang",age:20};
let obj1:{name?:string,arge:number}={age:20};//?可有可无
let obj1={};
obj1.name="zhangsan";
obj1.age=20;
let obj1:{[string]:string}={};
obj1.name="zhangsan";
obj1.age="20";
//函数类型
function foo(callback:(string,number)=>void){
callback("test",100);
}
//特殊类型
const a:"foo"="foo";//字面量
const tyep:"red" | "blue"="red";
type stringOrNumber=string|number;
const a:stringOrNumber="test";
//maybe类型(扩展了null和undefined类型)
const a:?number=undefined;
//Mixed类型
//mixed=string|number|...等所有类型
//Any类型
//any=string|number|...等所有类型
//any和mixed区别:any时弱类型不再进行语法检查,mixed时强类型仍然进行强类型检查,逻辑中需要进行typeof进行类型判断。
运行环境API: 内置对象
//这些内置函数的参数约定,来自于Flow自动下载的定义。
let a:HTMLElement=document.getElementById("test");
包含:Javascript、类型系统和ES6+
经过编译:javascript(可以选择版本)。
优点:
缺点:
#创建文件夹vscode打开
#初始化工程
npm init
#安装typescript环境
npm install typescript -D
文件扩展名.ts。
编译命令:tsc test.ts;
过程:语法检查->js新特性转换->转换为运行时js代码。
编译文件/编译工程。
#初始化工程
tsc --init
会生成tsconfig.json配置文件。
配置项:
const a: string = "test";
const b: number = 100; //NaN Infinity
const c: boolean = true;
const e: void = undefined;
const f: null = null;
const g: undefined = undefined;
//注:严格模式时,变量不可以为null和undefined,非严格模式可以。
//const d: boolean = null;
//配置文件:
//"target": "es5",
//"lib": ["ES2015","DOM"]
//标准库:就是内置对象对应的声明,如果引用不到就会报错。
const h: symbol = Symbol();
中文错误消息的设置:(日常使用中,不推荐)
编译过程:tsc --locale zh-CNvscode:设置中搜索typescript.local,然后设置zh-CN
作用域问题:
自执行函数,包装的方式。
export {}导出方式。推荐的方式
//函数
const a: object = function () {};
//必须完全一致
const b: { name: string; age: number } = { name: "张三", age: 20 };
//限制对象类型应该使用interface方式。
//数组类型
const arr1: Array = [1, 2];
const arr2: number[] = [1, 2];
function sum(...args: number[]): number {
return args.reduce((prev, current) => prev + current, 0);
}
sum(1, 2, 3);
//元组类型
const tuple: [number, string] = [20, "张三"];
//直接提取
// let age = tuple[0];
// let name = tuple[1];
//数组解构的方式
let [age, name] = tuple;
//枚举类型
enum Status {
No,
Yes,
}
enum Status1 {
No = "0",
Yes = "1",
}
enum Status2 {
No = 0,
Yes = 1,
}
let a = Status.Yes;
//枚举类型运行时的入侵,影响编译后的结果。
//双向键值对对象:目的是,可以通过索引器的方式访问枚举的名称。
let yes = Status[0];
//如果不适用这种方式获取名称,建议使用常量枚举
const enum Status3 {
No,
Yes,
}
let test = Status3.Yes;
//函数类型
//函数声明
function func1(a: number, b: number): number {
return a + b;
}
//可选参数,参数名称后增加?
function func2(a: number, b?: number): string {
return "你好";
}
//参数默认值
function func3(a: number, b: number = 6): number {
return a + b;
}
//注:可选参数或者默认值参数必须出现在参数列表的最后。
//任意个参数,使用rest运算符:...
function func4(a: number, b: number, ...args: number[]): number {
return a + b;
}
//函数表达式:
const func5 = function (a: number, b: number): number {
return a + b;
};
//箭头函数
const func6 = (a: number, b: number): number => a + b;
//函数接口方式
const func7: (a: number, b: number) => number = function (
a: number,
b: number
): number {
return a + b;
};
//任意类型any:不进行类型检查,轻易不要使用。
let a: any = 90;
a = "你好";
//隐式类型推断;
let age = 18;
//改变类型,会报错。
//age="12";
//不进行声明,则为any类型
let test;
test = 10;
test = "abc";
//类型断言
const nums = [100, 20];
const a = nums.find((i) => i > 0);
//会报错,ts不知道a的类型为number。
//let b = a + a;
//断言:as方式
const b = a as number;
let btest = b + b;
//断言:<>方式:注可能与jsx产生冲突,推荐使用as方式。
const c = a;
let ctest = c + c;
//接口
interface User {
name: string;
age: number;
birth?: string; //可选
readonly sex: string; //只读
}
function sayHello(user: User): string {
return user.name;
}
//只用于做类型约束,在实际代码运行中,找不到,也不会用。
//可选成员?
//只读成员:readonly
//动态方式
interface Person {
[prop: string]: string;
}
const person: Person = {};
//可以自由添加属性成员了
person.name = "zhangsan";
//类:ts增强了类的相关语法
//基本用法
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHi(wel: string): void {
console.log(wel + this.name);
}
}
//访问修饰符
class Person1 {
private name: string;
public age: number; //默认public
protected sex: boolean; //只允许子类访问
constructor(name: string, age: number) {
this.name = name;
this.age = age;
this.sex = true;
}
sayHi(wel: string): void {
console.log(wel + this.name);
}
}
class Man extends Person1 {
constructor(name: string, age: number) {
super(name, age);
this.sex = false; //子类可以访问
}
}
//构造函数也可以进行访问修饰
class Woman extends Person1 {
private constructor(name: string, age: number) {
super(name, age);
this.sex = true; //子类可以访问
}
static init(): Woman {
//static静态类
return new Woman("zhangsan", 20);
}
}
let w = Woman.init();
//只读属性
class Woman01 extends Person1 {
//只读属性,只可在声明或着构造函数立即声明
private readonly grade: number;
constructor(name: string, age: number) {
super(name, age);
this.grade = 10;
}
}
//类与接口
interface Person001 {
run(speed: number): void;
eat(food: string): void;
}
class Student001 implements Person001 {
run(speed: number): void {
console.log("run");
}
eat(food: string): void {
console.log("eat");
}
}
//抽象类(可以包含具体实现)
abstract class Student002 implements Person001 {
private name: string;
constructor(name: string) {
this.name = name;
}
run(speed: number): void {
console.log("run");
}
eat(food: string): void {
console.log("eat");
}
}
class Student003 extends Student002 {
constructor() {
super("张三");
}
}
let st = new Student003();
st.eat("馒头");
// 泛型
function createNumberArray(leg: number, value: number): number[] {
let arr = Array(leg).fill(value); // 泛型的使用方法
return arr;
}
//把类型变成参数
function createArray(leg: number, value: T): T[] {
let arr = Array(leg).fill(value); // 泛型的使用方法
return arr;
}
import { camelCase } from "lodash";
// 类型声明
//declare function camelCase(input: string): string;
let a = camelCase("hello");
export {};
由于typescript的社区能力,可以对于一些模块,安装类型声明,而提供各种的提示。
模块一般安装到开发环境--save-dev,例如:npm i @types/lodash --save-dev。
安装的文件一般都为:.d.ts的命名方式:专门用于类型声明。
注:有些模块,已经内部集成了类型声明文件。
进一步学习:TypeScript中文网 · TypeScript——JavaScript的超集
留言与评论(共有 0 条评论) “” |