1.安装 typescript 运行环境 需要安装:npm node typescript 2.运行 为方便运行 typescript转为javascript 直接使用ts-node 运行 (使用需要安装)
对静态类型的深入理解
基础类型//null,undefind,symbol,boolean,void(无返回值),never(阻止执行),number,string let count :number; count = 123; // 还有两个奇葩兄弟,undefined 和 null let u: undefined = undefined let n: null = null // 注意 undefined 和 null 所有类型的子类型。也就是说, undefined 类型的变量可以赋值 number 类型变量: let num: number = undefined any 类型 let notSure: any = 4 notSure = 'maybe it is a string' notSure = 'boolean' // 允许任何属性访问任何值: notSure.myName // 任何方法也可以调用: notSure.getName()
对象类型 //{},Class.function,[] const func = (str:string):number =>{
return parseInt(str,10); } const func:(str:string)=>number=(str)=>{
return parseInt(str,10); }
//其他类型 case let temp:number | string = 123; temp ='456'
//type annotation 类型注解,我们告诉TS变量是什么类型
let count :number;
count =123;
//type inference 类型推断,TS会自动分析变量的类型
let data =123;
//如果 ts能够自动分析变量类型,我们就什么也不需要做了
//如果ts无法分析变量类型,我们就需要使用类型注释
function get(a:number,b:number)
{
return a+b;
}
const total = getTotal(1,2);
函数相关类型
function get(a:number,b:number):number
{
return a+b;
}
const total = get(1,2);
//解构加类型注解
function add(
{
first, second }: {
first: number, second: number }): number{
return first + second;
}
//函数定义
普通定义
1.function hello(){
}
2.const hello =function(){
}
3.const hello=()=>{
}
高级定义
1.
const func = (str: string): number => {
return parseInt(str, 10);
}
2.
const func: (str: string) => number = (str) => {
return parseInt(str, 10);
}
数组
const arr:(number | string)[]=[1,'2',3];
const stringarr: string[]=['a','b','c'];
//类型别名 type alias
type User ={
name:string,age:number};
const objectArr :User[]=[{
name:'123',
age:28
}]
//元组 tuple
const arr:[string,string,number]=['123','456',18 ];
处理csv 数据
const arr :[string,string,number][]=[
['1','2',3],
['4','5','6'],
[],
]
//最简单的方法是使用「类型 + 方括号」来表示数组:
let arrOfNumbers: number[] = [1, 2, 3, 4]
//数组的项中不允许出现其他的类型:
//数组的一些方法的参数也会根据数组在定义时约定的类型进行限制:
arrOfNumbers.push(3)
arrOfNumbers.push('abc')
// 元祖的表示和数组非常类似,只不过它将类型写在了里面 这就对每一项起到了限定的作用
let user: [string, number] = ['viking', 20]
//但是当我们写少一项 就会报错 同样写多一项也会有问题
user = ['molly', 20, true]
Interface接口//帮助做语法校验的工具
interface Person {
readonly name;string;//readonly 只读模式
age?:string; // ? 使得 age 可有可无
[propName:string]:any;//可以添加其他属性,例如这个是以any的形式的属性
say(): string;//say表示接口里面要有一个方法,这个方法的返回值必须是string
}
//interface 与类型别名相似 但是interface只能代表 函数和对象
type person1 = string;
const getPersonName = (person :Person)=>{
console.log(person.name )
}
const person = {
name:'dell'
}
getPersonName(person)
// 我们定义了一个接口 Person
interface Person {
name: string;
age: number;
}
// 接着定义了一个变量 viking,它的类型是 Person。这样,我们就约束了 viking 的形状必须和接口 Person 一致。
let viking: Person ={
name: 'viking',
age: 20
}
//有时我们希望不要完全匹配一个形状,那么可以用可选属性:
interface Person {
name: string;
age?: number;
}
let viking: Person = {
name: 'Viking'
}
//接下来还有只读属性,有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性
interface Person {
readonly id: number;
name: string;
age?: number;
}
viking.id = 9527
类的的定义与继承
class Person{
name: string = "dell"//定义一个name属性
getName() {
//定义一个方法
return this.name;
}
}
//通过类创建一个实例
const person = new Person();
console.log(person.getName());
//类的继承
class Teacher extends Person{
getTeacherName() {
return 'Teacher';
}
getName() {
//类的重写
super.getName();//super 相当于Person这个父类,调用了Person里面的方法,当父类的方法被重写之后,如果想调用被重写之前的父类方法,就可以使用super
return 'leen';
}
}
const teacher = new Teacher();
console.log(teacher.getName());
console.log(teacher.getTeacherName());
枚举
1.创建枚举
enum 枚举名称{
成员1,成员2,...}
创建枚举通过enum关键字创建,关键字后面加上枚举名称,在后面加上花括号,花括号里面放入枚举的成员,枚举成员可以有多个。
枚举名称、成员名称首个字母大写,多个成员之间用逗号隔离。
示例:
//家庭枚举:妈妈,爸爸和我
enum Family {
Mom,Father,Me}
2.使用枚举
枚举是一种类型,可以作为变量的类型注释。
enum Gender {
Female,Male}
let userGender:Gender
访问枚举中的成员,作为变量的值
userGender = Gender.Female
userGender = Gender.Male
值得注意的是:枚举中的成员只能访问,不能赋值。
Gender.Female = '男' //错误
// 数字枚举,一个数字枚举可以用 enum 这个关键词来定义,我们定义一系列的方向,然后这里面的值,枚举成员会被赋值为从 0 开始递增的数字,
enum Direction {
Up,
Down,
Left,
Right,
}
console.log(Direction.Up)
// 还有一个神奇的点是这个枚举还做了反向映射
console.log(Direction[0])
// 字符串枚举
enum Direction {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT',
}
const value = 'UP'
if (value === Direction.Up) {
console.log('go up!')
}
类的访问类型和构造器
// private , protected, public
//public 允许我在类得内外被调用
//private 允许在类内被调用
//protected 允许在类内及继承的子类中使用
class Person {
protected name: string;
public sayHi() {
this.name;
console.log('hi');
}
}
const person = new Person();
person.name = 'dell';
person.sayHi();
class Teacher extends Person{
//继承的子类,Person 是父类Teacher是子类
}
//constructor 构造器
class Person {
//传统写法
//public name:string;
constructor(name: string) {
this.name = name;
}
//简化写法
constructor(public name: string) {
this.name = name;
}
}
const person = new Person('dell');
console.log(person.name)
//一个类被子类调用,如果子类要用构造器的话,调用父类构造器时用super并且按照父类的参数要求传参数
class Person{
constructor(public age:string){
}
}
class Teacher extends Person{
constructor(public age:nmuber){
super('dell);
}
}
const teacher = new Teacher(28);
console.log(teacher.age)
console.log(teacher.number)
静态属性
Setter/Getter
通过set/get,完成对私有属性的开放和封装。
class Person4GetOrSet {
// 一般用下划线_表示私有属性
constructor(private _name: string) {
}
// 定义对外开放属性
get name() {
return this._name;
}
// 赋值定义,这边也可以做一些赋值过滤处理
set name(name: string) {
this._name = name;
}
}
const person = new Person4GetOrSet("张三");
console.log(person.name);
person.name = "李四";
console.log(person.name);
抽象类
编译运转过程
typescript中的配置文件
tsconfig.ts
联合类型和类型保护
1. 联合类型
什么是联合类型
联合类型(Union Types)表示取值可以为多种类型中的一种。
联合类型使用 | 分隔每个类型。
let testNumber: string | number;
testNumber = 'six';
testNumber = 8;
// 这里的string | number的含义是,允许testNumber的类型是string或者number,但是不能是其他类型。
访问联合类型的属性或方法
当TypeScript不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问联合类型的所有类型里共有的属性或方法。
interface Bird {
fly: boolean;
sing: () => {
};
}
interface Dog {
fly: boolean;
bark: () => {
};
}
function trainAnialCommon(animal: Bird | Dog) {
animal.fly;
}
2. 类型保护
什么是类型保护
类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型。
为什么需要类型保护
正如上文出现的联合类型,当一个变量具备多种类型的时候,虽然我们知道代表着什么类型,但是编译器是死的,它是无法知道具体的类型,这个时候就需要我们手动就处理,保护我们的程序能够正常编译运行。
怎么实现类型保护?
方式一: 使用as 类型断言的方式
interface Bird {
fly: boolean;
age: number;
sing: () => {
};
}
interface Dog {
fly: boolean;
age: string;
bark: () => {
};
}
/** * 使用as 类型断言的方式 * @param animal */
function trainAnial(animal: Bird | Dog) {
// 写法一
if (animal.fly) {
(animal as Bird).sing();
} else {
(animal as Dog).bark();
}
// 写法二
if (animal.fly) {
(<Bird>animal).sing();
} else {
(<Dog>animal).bark();
}
}
方式二:in 语法来做类型保护
/** * in 语法来做类型保护 * @param animal */
function trainAnialSecond(animal: Bird | Dog) {
if ("sing" in animal) {
animal.sing();
} else {
animal.bark();
}
}
方式三:typeof 语法来做类型保护
/** * typeof 语法来做类型保护 * @param first * @param second */
function add(first: string | number, second: string | number) {
if (typeof first === "string" || typeof second === "string") {
return `${
first}${
second}`;
}
return first + second;
}
方式四:使用 instanceof 语法来做类型保护
/** * 使用 instanceof 语法来做类型保护 */
class NumberObj {
conut: number;
}
function addSecond(first: object | NumberObj, second: object | NumberObj) {
if (first instanceof NumberObj && second instanceof NumberObj) {
return first.conut + second.conut;
}
return 0;
}
Enum枚举类型
1. 什么是枚举
枚举(Enum)类型用于取值被限定在一定范围内的场景,TypeScript支持数字的和基于字符串的枚举。
关键字:enum
2. 怎么去定义枚举
数字枚举定义
enmu Status {
ON,
OFF
}
// 访问取值
console.log(Status.ON); // 0
// 访问取枚举
console.log(Status[0]); // ON
默认数值从0开始排序,当然和可以自定义 ,如果ON表示1,其余的成员会从1开始自定增长。
注意:手动赋值时,注意值覆盖的情况,这种ts是无法检测报错的。
enum Months {
JAN = 4,
FEB = 1,
MAR,
APR,
MAY,
JUN,
JUL,
}
手动赋值也可以是小数,比如FEB=1.5,但是递增的步长依旧会是1
如果手动赋值的枚举项不是数字,此时需要使用类型断言来让tsc无视类型检查。
JUL = <any>"jul",
函数泛型
generics 泛指的类型
泛型的定义和使用
使用泛型可以创建泛型变量、泛型函数、泛型接口、泛型类,不可以创建泛型枚举和泛型命名空间
创建泛型变量,表示这些参数是任意或者所有类型,只有使用的时候,才能被确定是什么类型。
// first: T 和 second: T 就是一个泛型变量
function join<T>(first:T,second:T){
return `${
first} + ${
second}`;
}
join<number>(1,1);//使用的时候就确定number类型
//多个泛型
function join<T,p>(first:T,second:p){
return `${
first} + ${
second}`;
}
join<number,number>(1,1)
泛型约束
function echoWithArr<
标签: viking氧化膜电阻器