typescript笔记
为什么没有二级标题?
搭建开发换环境
安装nodejs
全局安装
typesctipt
npm i -g typescript
创建一个ts文件:
使用tsc对文件进行编译:
tsc xxx.ts
基本类型
类型声明:
声明一个变量a,同时制定它的类型为number,
a设置为了string,在以后的使用过程中a的值只能是string
const a: string = 'fuck you also !';// 或者:
const b:string;
b = 'fuckyou';
注意:
在typescript中如果写的有错误代码,但是可以编译为js
ts编译可以编译为任意版本的js,默认是编译为较低版本的js
自动推断类型
如果变量的声明和赋值是同时进行的,ts可以自动对变量进行类型检测
let c = false;
// 这里会报错,因为在上面使用时已经制定其为boolean类型
c = 'fuckyou';
指定function传参类型:
function sum(a: number, b: number): number {return a + b
}const res = sum(5, 8);
指定function返回的数值类型:
其中():后面的类型就是指定的方法返回类型
function sum(a: number, b: number): number {return a + b
}
基本类型:
数据类型 | 关键字 | 描述 |
---|---|---|
任意类型 | any | 声明为 any 的变量可以赋予任意类型的值。 |
数字类型 | number |
双精度 64 位浮点值。它可以用来表示整数和分数。let binaryLiteral: number = 0b1010; // 二进制 let octalLiteral: number = 0o744; // 八进制 let decLiteral: number = 6; // 十进制 let hexLiteral: number = 0xf00d; // 十六进制
|
字符串类型 | string |
一个字符系列,使用单引号(')或双引号(")来表示字符串类型。反引号(****)来定义多行文本和内嵌表达式。 let name: string = “Runoob”; let years: number = 5; let words: string = 您好,今年是 ${ name } 发布 ${ years + 1} 周年 ;`
|
布尔类型 | boolean |
表示逻辑值:true 和 false。let flag: boolean = true;
|
数组类型 | 无 |
声明变量为数组。// 在元素类型后面加上[] let arr: number[] = [1, 2]; // 或者使用数组泛型 let arr: Array<number> = [1, 2];
|
元组 | 无 |
元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。let x: [string, number]; x = ['Runoob', 1]; // 运行正常 x = [1, 'Runoob']; // 报错 console.log(x[0]); // 输出 Runoob
|
枚举 | enum |
枚举类型用于定义数值集合。enum Color {Red, Green, Blue}; let c: Color = Color.Blue; console.log(c); // 输出 2
|
void | void |
用于标识方法返回值的类型,表示该方法没有返回值。function hello(): void { alert("Hello Runoob"); }
|
null | null | 表示对象值缺失。 |
undefined | undefined | 用于初始化变量为一个未定义的值 |
never | never | never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。 |
字面量的创建:
- 字面量创建后无法修改,类似于const:
// 使用字面量进行类型声明
let g: 310;// 使用字面量之后下面无法赋值,会报错
// g = 65;
// g = 5;
- 字面量可以限制其值:
// 也可以在创建字面量的时候使用|链接多个值:
let h: "fuck you" | "son of bitch" | "shameless";
console.log(`h:${h}`)
- 限制字面量的类型:
//也可以指定其为多个类型:
let flag: boolean | string;
flag = true;
flag = "fuck the world";
any:
一个变量设置为any后,就会对该变量关闭类型检测,但开发中不建议使用
显式any,在声明时,不指定类型
let b;
隐式any
any不仅影响自己,同时也会影响与它相关的:
let u:any;
u='123465';
let o:string;
//下面这个不会报错,any可以复制给任意变量
o=u;
- 但是有些情况我们不知道传入的值的类型
可以使用unknown 表示未知类型的值
let y: unknown;
y = 10;
y = 'sad';
let p:'fuck';
//将ubknown赋值给其他类型时,会报错,区别于any
p=y;
//unknown实际上就是一个类型安全的any
避免unknown赋值错误可以:
let y: unknown;
y = 10;
y = 'sad';
let p:'fuck';
// 将ubknown赋值给其他类型时,会报错,区别于any
// p=y;
if(typeof p=='string'){p=y;
}
类型断言
let y: unknown;
y = 10;
let p:'fuck';
// 判断,他可以用来告诉解析器变量的实际类型
p = y as string;
p = <string> y;
void一般作为返回值
// 有返回值:
function fn1(): boolean {return false
}console.log(fn1())// 表示该函数没有返回值
function fn2(): void {console.log('fuck you! fn2')
}fn2();
never 表示永远不会返回结果:
// never 表示永远不会返回结果:
function fn3(): never {throw new Error('报错');
}
fn3();
设置函数结构的类型声明
// 限定一个function的传参和返回值:
// 设置函数结构的类型声明
let d: (a: number, b: number)=>number;
d = function (n1, n2) {return n1 + n2;
}
数组(array)
// 表示字符串数组
let e: string[];
e = ['s', 'g', 'sc'];
// number类型数组
let u: Array<number>;
u = [2, 5, 1, 5, 6, 4];
let d3: Array<number>;
d3 = [2, 5, 65, 32, -123];
两种表示方式
元祖(tuple)
//元祖,固定长度的数组,但数组中的值是固定的,使用元祖比较好
let h: [string, string];h = ['hello', 'world'];
对象(object)
在js中对象什么都可以存储:
// js中的对象
let c2 = {name: '八嘎',age: 15,gender: '男'
};
但在ts中我们可以指定tys中存储的属性类型:
// 指定属性名: propName 指定属性值:any
let c: {name: string,[propName: string]: any
};c = {name: '椎间孔',school: 'fuck you school!'
}
console.log('c:');
console.log(c);
其中[propName: string]: any
指定其属性名为任意值
对于不确定是否设置的属性可以使用?
表示这个属性是可选的
let c: {name: string,age?: number,[propName: string]: any
};
函数(function)
/*
箭头函数的形式设置函数的类型声明,
语法:(形参:类型,形参:类型...)=>返回值
* */
let s: (a: number, b: number) => number;
//下面传入两个参数是符合定义的
s = function (n1, n2) {return n1 + n2;
}
// 如果传入三个参数,报错
/*s = function (n1, n2, n3) {return n1 + n2;
}*/
枚举(enum)
// 定义枚举:
enum Gender {Male,Female
}
let i: { name: String, gender: Gender }
i = {name: 'zjk',gender: Gender.Female
}console.log(i.gender == Gender.Male);// &表示同时:
let j: { name: string } & { age: number };
j = {name: '猴子', age: 15};
类型别名
type myType = string;
type myKey = 1 | 2 | 3 | 4 | 5
let k: myKey;
let m: myType
&表示必须有的多个值
// & 用来连接,表示该值必须有指定的类型参数
let o: { name: string } & { age: number };
o = {name: 'fuc',age: 23
};
编译选项
- 自动编译文件:
编译文件时,使用-w指令后ts编译器会自动监视文件的变化,并在文件发生变化时对文件进行重新编译
示例:
tsc xxx.ts -w
但是这种方式每一个文件都要单独开一个窗口,不适合开发的
设置编译所有ts文件:
在需要编译的目录下新建ts的配置文件:
tsconfig.json
你可以使用的模板:
{"compilerOptions": {// 采用的模块系统"module": "es6",// 编译输出目标 ES 版本"target": "es6",// 删除所有注释,除了以 /!*开头的版权信息。"removeComments": true}
}
这里你也可以什么都不写:
{}
在什么都不写的情况
下运行:
PS D:\myHomeWork\project\WebStudy\typescript\part02> tsc
PS D:\myHomeWork\project\WebStudy\typescript\part02> dir目录: D:\myHomeWork\project\WebStudy\typescript\part02Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/3/15 13:47 49 01.js
-a---- 2023/3/15 13:41 59 01.ts
-a---- 2023/3/15 13:47 64 02.js
-a---- 2023/3/15 13:47 68 02.ts
-a---- 2023/3/15 13:45 239 tsconfig.json
该目录下的ts文件都被编译了
当然,也可以使用tsc -w
监视该文件夹下所有的ts文件
include
include 用来指定哪些ts文件需要被编译:
/*
ts编译器的配置文件,
ts编译器可以根据它的信息来对代码进行编译include 用来指定哪些ts文件需要被编译其中 ** 表示任意目录, * 表示任意文件*/
{"include": ["./src/**/*"]
}
exclude
exclude 用来排除
- 默认值:[“node_modules” , “bower_components” , “jspm_packages”]
{"include": ["./src/**/*"],"exclude": ["./src/hello/**/*"]
}
extends
- 定义被继承的配置文件
- 示例:
"extends":"./config/base"
- 上述示例中,当配置文件中会自动包含config目录下config目录下base.json中的所有配置信息
compilerOptions
- 编译器的选项,是配置文件中非常重要也比较复杂的配置选项
- 在 compilerOptions 中包含多个子选项,用来完成对编译的配置
项目选项
target
用来指定ts被编译的es版本,默认情况下ts会被转为es3版本的js
{ "include": [ "./src/**/*" ],"compilerOptions": { "target": "es6" }
}
如果值为ESNext
表示编译为最新版本的es
注意
:如果不知道有哪几个版本,可以乱填一个,编译报错会告诉你可以填哪些版本
lib
- 用来指定项目中要使用的库
- 一般情况下不动它
module
- 模块
指定要使用的模块化规范
{ "include": [ "./src/**/*" ], "compilerOptions": { "target": "es6", "module": "es2015", }
}
outDir
- 用来指定编译后文件所在的目录
{ "include": [ "./src/**/*" ], "compilerOptions": { "target": "es6", "module": "es2015", "lib": [], "outDir": "./dist" }
}
outFile
将编译后的ts文件打包为一个文件
设置outFile之后,所有的全局作用域中的代码会合并到同一个文件中
如果你想要合并自己的js文件,那么需要将modules改为system:
"module": "system",
allowJs
是否编译指定目录下的js文件:
"allowJs": false
如果为false,那么编译时不会编译js文件,只会编译ts文件
checkJs
检查js代码是否符合规范
默认为false
"checkJs": false,
removeComments
是否移除注释
默认值为false
"removeComments": false
noEmit
不生成编译后的文件
"noEmit": false
noEmitOnError
有错误时不生成编译文件
默认值为false
"noEmitOnError": false
alwaysStrict
设置编译后的js是否使用严格模式
并且在浏览器中执行的性能要好一些
默认为false
"alwaysStrict": false
设置为true:
在编译后的js文件头部加上:
"use strict";
注意:
对于有export
,import
这些导出导入模块的js文件,它是不会加上"use strict";
,因为它已经自动使用了严格模式
noImplicitAny
设置没有指定参数类型时,是否允许推断其为any类型
开发中我们要避免显式的any,
对于下面的代码就是使用的是显式any,需要避免:
function fn(a, b) { return a + b
}
默认是为true
"noImplicitAny": false
如果 为false,那么像是下面的代码就会报错:
function fn(a, b) { return a + b
}
此时如果加上类型就不会报错了:
function fn(a: number, b: number) { return a + b
}
noImplicitThis
是否允许不明确类型的this
"noImplicitThis": true
默认为true
此时为false,那么下面就会报错:
function fn2() {// 下面这个this是不明确的alert(this);
}
当你指定后就不再报错:
function fn2(this: Window) {// 下面这个this是不明确的alert(this);
}
strictNullChecks
严格的检查空值
默认值为false
如果改为true:
"strictNullChecks": true
对于下面的ts代码:
let box1 = document.getElementById("box1");
box1.addEventListener("click", function () {console.log('click')
})
这里的box1可能为空,那么在编译的时候就会报错
可以这样解决:
let box1 = document.getElementById("box1");
if (box1 != null) {box1.addEventListener("click", function () {console.log('click')})
}
或者使用?:
let box1 = document.getElementById("box1");
box1?.addEventListener("click", function () {console.log('click')
})
strict
所有严格检查的总开关,如果这个为true,那么下面几个都可以不写,一般开发建议写true所有严格检查的总开关,如果这个为true,那么下面几个都可以不写,一般开发建议写true
"strict": true,
可以省略下面这几个:
noEmitOnError,
alwaysStrict,
noImplicitAny,
noImplicitThis,
strictNullChecks
通过webpack对ts编译
最基础的配置:
目录结构:
PS D:\myHomeWork\project\WebStudy\typescript\part03> dir目录: D:\myHomeWork\project\WebStudy\typescript\part03Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2023/3/16 11:33 dist
d----- 2023/3/16 11:36 node_modules
d----- 2023/3/16 11:34 src
-a---- 2023/3/16 11:37 472 package.json
-a---- 2023/3/16 11:25 103 tsconfig.json
-a---- 2023/3/16 11:35 557 webpack.config.js
package.json
:
{"name": "part03","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","start": "webpack server --open"},"author": "","license": "ISC","dependencies": {"html-webpack-plugin": "^5.5.0","ts-loader": "^9.4.2","typescript": "^4.9.5","webpack": "^5.76.2","webpack-cli": "^5.0.1","webpack-dev-server": "^4.12.0"}
}
tsconfig.json
:
{"compilerOptions": {"target": "ES2015","module": "ES2015","strict": true}
}
webpack.config.js
:
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin')module.exports = {entry: "./src/index.ts", output: {path: path.resolve(__dirname, 'dist'), filename: 'bundle.js',}, module: {rules: [{test: /\.ts$/, use: 'ts-loader', exclude: /node_modules/}]},// 插件:plugins: [new htmlWebpackPlugin({// 自定义生成文件的title// title: 'index title'// 自定义模板template: './src/index.html'})]
}
这里主要是使用webpack.config.js中的配置文件
兼容目标浏览器版本:
package.json
:
{"name": "part03","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","start": "webpack server --open"},"author": "","license": "ISC","dependencies": {"@babel/core": "^7.21.3","@babel/preset-env": "^7.20.2","babel-loader": "^9.1.2","clean-webpack-plugin": "^4.0.0","core-js": "^3.29.1","html-webpack-plugin": "^5.5.0","ts-loader": "^9.4.2","typescript": "^4.9.5","webpack": "^5.76.2","webpack-cli": "^5.0.1","webpack-dev-server": "^4.12.0"}
}
tsconfig.json
:
{"compilerOptions": {"target": "ES2015","module": "ES2015","strict": true}
}
webpack.config.js
:
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')module.exports = {entry: "./src/index.ts", output: {path: path.resolve(__dirname, 'dist'), filename: 'bundle.js',}, module: {rules: [{test: /\.ts$/,// 这里的使用顺序是从后往前use: [{loader: 'babel-loader',options: {presets: [["@babel/preset-env",// 配置信息:{// 要兼容的目标版本targets: {"chrome": "88"},"core-js": "3",// 使用模式,这里设置的是按需加载"useBuiltIns": "usage"}]]}},'ts-loader'],exclude: /node_modules/}]},// 插件:plugins: [new htmlWebpackPlugin({// 自定义生成文件的title// title: 'index title'// 自定义模板template: './src/index.html'}),new CleanWebpackPlugin()]
}
面向对象
面向对象简介
对象中主要包含两个部分:
- 属性
- 方法
定义类:
class 类名{静态属性/实例属性方法(){}
}
- 示例:
class Person {private name: string;private age: number;// 定义实例属性(通过定义实例才能看到的属性为实例属性)grade: string = '大三';// 当然也可以不写类型gre = '孙悟空';// 使用static定义静态属性,静态属性要通过类来访问static word: string = 'fuck you!';// 定义只读属性,它无法修改readonly only: string = 'fuck you only read';// 定义一个静态的只读属性static readonly onlyStatic: string = 'fuck you only onlyStatic';constructor(name: string, age: number, grade?: string) {this.name = name;this.age = age;}sayName() {console.log('我是' + this.name);}sayAge() {console.log('我的年龄是' + this.age);}
}console.log("Person.word:")
console.log(Person.word)const p1 = new Person('张三', 15, "高二")
console.log(p1)
console.log("p1.only:")
console.log(p1.only)
console.log('Person.onlyStatic,静态只读属性:')
console.log(Person.onlyStatic)console.log('p1的name:')
p1.sayName()
console.log('p1的age:')
p1.sayAge()
定义一个方法
- 实例方法
可以直接在类中使用:
class Person {private name: string;private age: number;constructor(name: string, age: number, grade?: string) {this.name = name;this.age = age;}sayName() {console.log('我是' + this.name);}sayAge() {console.log('我的年龄是' + this.age);}
}
- 静态方法:
class Person {private name: string;private age: number;constructor(name: string, age: number, grade?: string) {this.name = name;this.age = age;}sayName() {console.log('我是' + this.name);}sayAge() {console.log('我的年龄是' + this.age);}static func(){console.log('这是一个类调用的function')}
}
要注意静态方法只有类可以调用,实例无法调用
构造函数
class Constructor {name: string | undefined = '普通的狗';age: number | undefined = 5;// 在实例方法中,this就是表示当前的实例// 在构造函数中当前对象就是当前新建的那个对象// 可以通过this向新建的对象中添加属性constructor(name?: string, age?: number) {this.name = name;this.age = age;}
}
继承
例如在下面的代码中
// 继承
(function () {class Dog {name: string | undefined;age: number | undefined;constructor(name?: string, age?: number) {this.name = name;this.age = age;}sayHello() {console.log('hello,汪汪汪')}}class Cat {name: string | undefined;age: number | undefined;constructor(name?: string, age?: number) {this.name = name;this.age = age;}sayHello() {console.log('hello,喵喵喵')}}const dog = new Dog("旺财1", 23);dog.sayHello();const cat = new Cat("肥仔", 20)cat.sayHello();
})();
他们的name,age属性一模一样的,如果我们想要去创建其他动物,并且有name和age,那么就为了避免这些重复
#### super
- 在方法中super表示当前的父类
(function () {class Animal {name: string;constructor(name: string) {this.name = name;}sayHello() {console.log('动物在叫')}}class Dog extends Animal {sayHello() {// 在方法中super表示当前的父类super.sayHello();}}const dog = new Dog("张三");dog.sayHello();
})();
- 如果在子类中重写了父类的构造函数,那么在子类构造函数中必须对父类的构造函数重写
(function () {class Animal {name: string;constructor(name: string) {this.name = name;}sayHello() {console.log('动物在叫')}}class Dog extends Animal {age: number;sayHello() {// 在方法中super表示当前的父类super.sayHello();}// 如果在子类中重写了父类的构造函数,那么在子类构造函数中必须对父类的构造函数重写// 子类的构造函数中传递的属性必须把父类中需要传递的属性也写上constructor(name: string, age: number) {// 调用父类的构造函数super(name);this.age = age;}}const dog = new Dog("张三", 23);dog.sayHello();
})();
如果这里子类的constructor
中没有super父类的传递属性,会报错
抽象类
一些父类是用作被继承的,而且我们不希望它被实例化,那么此时就可以使用abstract
来修饰这个类:
// 抽象类
(function () {// 使用 abstract 表示该类为一个抽象类,无法被实例化,只能被继承abstract class Animal {name: string;constructor(name: string) {this.name = name;}sayHello() {console.log('动物在叫')}}class Dog extends Animal {sayHello() {// 在方法中super表示当前的父类super.sayHello();}}const dog = new Dog("张三");dog.sayHello();
// 此时animal也可以创建对象,但是我们不希望用animal来创建对象
})();
使用 abstract 表示该类为一个抽象类,无法被实例化,只能被继承
重现类中可以写抽象方法
抽象方法
抽象方法使用 abstract 修饰
抽象方法只能写在抽象类中,子类必须对抽象方法进行重写
例如:
// 抽象类
(function () {// 使用 abstract 表示该类为一个抽象类,无法被实例化,只能被继承abstract class Animal {name: string;constructor(name: string) {this.name = name;}// 抽象方法使用 abstract 修饰// 抽象方法只能写在抽象类中,子类必须对抽象方法进行重写abstract sayHello(): void;}class Dog extends Animal {sayHello() {// 在方法中super表示当前的父类console.log('狗在叫')}}const dog = new Dog("张三");dog.sayHello();
// 此时animal也可以创建对象,但是我们不希望用animal来创建对象
})();
接口
定义对象结构
- 接口用来定义一个类结构的,用来定义一个;类中应该包含哪些属性和方法
- 时接口也可以当成类型声明来使用
- 接口是可以重复声明的
- 如果有两个同名接口,生效是两个同时生效
// 接口
(function () {type myType = {name: string,age: number};/*接口用来定义一个类结构的,用来定义一个;类中应该包含哪些属性和方法同时接口也可以当成类型声明来使用接口是可以重复声明的如果有两个同名接口,生效是两个同时生效* */interface myInterface {name: string;age: number;}interface myInterface {gender: string;sayHell(): void;}const obj: myType = {name: 'zs',age: 12};const obj2: myInterface = {name: 'zs',age: 12,gender: '男',sayHell() {console.log('对象中的sayHello')}};
})();
定义类结构
接口在定义类的时候可以去限制类的结构
- 接口中所有的属性都不能有实际的值
- 接口只定义对象的结构,而不考虑实际值
- 在接口中的方法都是抽象方法
定义类时,可以使类去实现一个接口
实现接口就是使类满足接口的需求
// 接口
(function () {interface myInterface {name: string;age: number;}interface myInterface {gender: string;sayHell(): void;}/*接口在定义类的时候可以去限制类的结构接口中所有的属性都不能有实际的值接口只定义对象的结构,而不考虑实际值在接口中的方法都是抽象方法* *//*定义类时,可以使类去实现一个接口实现接口就是使类满足接口的需求* */class inst implements myInterface {name: string;age: number;gender: string;constructor(name: string, age: number, gender: string) {this.name = name;this.age = age;this.gender = gender;}sayHell(): void {console.log('inst sayHello')}}
})();
属性的封装
公有,私有属性
像是下面这个类,它定义的属性都可以在类的外面被访问到:
class Person {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}}
const per = new Person('猴子', 18);// 现在属性是在对象中设置的,属性可以任意的被修改// 属性可以被任意修改,导致我们对象中的数据非常不安全
per.name = '猪'
console.log(per)
在这种情况下对某些属性的修改可能会不安全,因此可以将不想修改的属性设置为私有属性:
class Animal {// public修饰的属性可以在任意位置访问(修改) 默认值// private私有属性,私有属性只能在类内部进行访问(修改)/*我们可以在类中添加方法使其私有属性在类的外面可以被访问* */private _name: string;private _age: number;private gender: number;constructor(name: string, age: number, gender: number) {this._name = name;this._age = age;this.gender = gender;}}
- 属性默认为public,public可以在任意位置被访问,包括子类
修改和获取私有属性
属性就是用来获取和使用的,因此,设置和获取私有属性时,可以通过在类中为其设置方法:
class Animal {// public修饰的属性可以在任意位置访问(修改) 默认值// private私有属性,私有属性只能在类内部进行访问(修改)/*我们可以在类中添加方法使其私有属性在类的外面可以被访问* */private _name: string;private _age: number;private gender: number;constructor(name: string, age: number, gender: number) {this._name = name;this._age = age;this.gender = gender;}// 像下面一样,可以使用这些方法来设置和访问到其私有属性getName(): string {return this._name;}setName(value: string) {this._name = value;}getAge(): number {return this._age;}setAge(value: number) {this._age = value;}}const a1 = new Animal('狗', 10, 20);// 虽然下面这个可以编译为js,但在ts中会报错,如果不想在有错误的情况下也通过编译,可以在 tsconfig 中配置有错不会编译为js// a1.gender = '猫'a1.setName('傻猫');console.log(a1)
- get和set方法被称为属性的存取器
存取器有另一种写法:
class Animal {private _name: string;private _age: number;private _gender: number;constructor(name: string, age: number, gender: number) {this._name = name;this._age = age;this._gender = gender;}// ts中设置get方法可以:get name(): string {return this._name;}set name(value: string) {this._name = value;}get age(): number {return this._age;}set age(value: number) {this._age = value;}get gender(): number {return this._gender;}set gender(value: number) {this._gender = value;}}const a1 = new Animal('狗', 10, 20);// 虽然下面这个可以编译为js,但在ts中会报错,如果不想在有错误的情况下也通过编译,可以在 tsconfig 中配置有错不会编译为js// a1.gender = '猫'// a1.setName('傻猫');console.log(a1.name)a1.name = '猪'console.log(a1)
- 这种方法不会改变我们已有的习惯
get:
console.log(a1.name)
set:
a1.name = '猪'
protected
protected 受保护的类,这个属性只能在当前类和其子类中被访问
protected word: string;
属性定义在构造函数中
直接把属性写在构造器中:
class Fruit {constructor(public name: string, public age: number) {this.name = name;this.age = age;}
}
泛型
- 在一个变量不明确类型的时候整一个泛型来表示这个变量的类型
泛型的定义
下面是一个普通的函数:
function fn1(a: number): number {return a
}
但是如果此时你并不确定该输入哪种的变量类型,那么此时就可以使用泛型:
function fn2<T>(a: T): T {return a
}
在使用时:
function fn2<T>(a: T): T {return a
}// 或者不指定泛型,ts可以自动对类型进行判断
fn2(20)
// 指定泛型
fn2<string>('hello')
当然也可以为多个形参指定泛型:
function fn3<T, R>(a: T, b: R): T {console.log(b)return a
}// 最好手动将泛型指定,降低出错的几率
fn3('fn', 369)
使用接口对泛型做出限制:
// 如果想通过接口对泛型做出限制:
interface Inter {length: number;
}// T extends Inter 表示泛型T必须实现Inter实现类(子类)
function fn4<T extends Inter>(a: T) {return a.length;
}
当然,类也可以使用接口来对其做出数据类型做出限制:
interface Inter {length: number;
}class MyClass<T> {name: T;constructor(name: T) {this.name = name;}
}const mc = new MyClass('猴子')
typescript笔记相关推荐
- TypeScript笔记(5)—— 基本数据类型
TypeScript(5):基本数据类型 CSDN:jcLee95 邮箱:291148484@163.com 专题目录:https://blog.csdn.net/qq_28550263/catego ...
- TypeScript笔记(基础大全到井格游戏案例)
TypeScript学习笔记 参考文档 参考视频 一.介绍 TypeScript(Typed JavaScript at Any Scale):添加了类型系统的 JavaScript,适用于任何规模的 ...
- Typescript笔记之基础知识(1):强类型语言和弱类型语言、静态语言和动态语言
foreword(前言) 这是本人关于Typescript的第一篇笔记,之所以选择将"强类型语言和弱类型语言.静态语言和动态语言"作为第一个想要去总结的主题,是因为个人觉得它很重要 ...
- Typescript笔记-总
1. TS的数据类型 TS常用类型 类型 描述 String 字符串类型 Nubmer 数字类型 Boolean 布尔值类型 Object 对象类型 Array 数组类型 any 任意类型(不推荐) ...
- typescript笔记一:基础类型
1. TS的数据类型 TS常用类型 类型 描述 String 字符串类型 Nubmer 数字类型 Boolean 布尔值类型 Object 对象类型 Array 数组类型 any 任意类型(不推荐) ...
- 2. TypeScript笔记
1. 安装node.js之后 需要测试npm命令 2.命令正常安装TypeScript 3.安装Egret egret 命令 转载于:https://www.cnblogs.com/dxqNet/p/ ...
- TypeScript笔记 5--变量声明(解构和展开)
解构是什么 解构(destructuring assignment)是一种表达式,将数组或者对象中的数据赋给另一变量. 在开发过程中,我们经常遇到这样问题,需要将对象某个属性的值赋给其它两个变量.代码 ...
- TypeScript笔记(4)—— TypeScript中的类型注解
TypeScript(4):类型注解 [导读]JavaScript是若类型语言,而TypeScript里的类型注解是一种轻量级的为函数或变量添加约束的方式,为我们提供了静态类型分析能力,这样我们就可以 ...
- TypeScript笔记(3)—— 使用WebPack工具
TypeScript(3): 使用WebPack工具 作者:李俊才 CSDN:jcLee95 邮箱:291148484@163.com 专题目录:https://blog.csdn.net/qq_28 ...
- TypeScript笔记(1)——环境配置与第一个ts程序
TypeScript(1):开发环境配置与第一个ts程序 李俊才 CSDN:jcLee95 作者博客地址:https://blog.csdn.net/qq_28550263?spm=1000.2115 ...
最新文章
- MUV LUV EXTRA 2019CCPC秦皇岛站J题 KMP
- 2017-9-14-Linux移植:加快Linux主机的启动速度
- js里面字符数字和数字相加_「译」5 个奇怪的只会在 JS 里才发生的趣事
- 可以在没有main()的情况下编写C程序吗?
- js 运算符 语句
- moment 24小时与12小时区别
- java kettle6_java 调用kettle 6.1 转换
- 乐视入股酷派,手机圈全面战争已开打
- 推荐系统(Recommendation system )
- 免费搭建私人云盘+内网渗透+不限速无限存储
- 计算机的网线连接路由器的什么接口,tp-link路由器网线插哪个口 tplink路由器网线连接图解...
- 平行四边形图案c语言,使用scratch绘制各种图案-平行四边形【解说】
- LDU训练赛:小srf的游戏 单调队列 + DP
- 学编程难吗?多久能入门?
- 已斥资250亿!东京奥运会的AI黑科技能否如期亮相?
- 4.决策树的探赜索隐
- python3 sleep 延时秒 毫秒
- 深入了解示波器(一):示波器分类
- 软件需求——需求规格说明书模版(三)
- type 和 interface的区别
热门文章
- SwiftUI 特效之全屏烟花效果解析sks SKScene SKEmitterNode (教程含源码)
- 斯坦福大学神经网络_斯坦福大学欺骗专家和网络安全首席执行官解释了为什么人们迷上网络骗局
- 关于windows系统影子账户的问题
- 320亿美元收购ARM出价过高?软银股价跌幅超10%
- XXL-JOB详解(整合springboot)保姆级教程
- 大数据之Hive:hive中的cross join函数
- adobe acrobat reader dc2020中文版
- VR全景图拍摄制作和传统摄影的区别
- 雷军发全员信祝贺,小米手机销量超过苹果,晋升全球第二!
- 百度竞价投放策划案分享