TypeScript的特点
- 静态类型
- 会被编译成普通的
JavaScript
来运行 - 编写代码的时候可以快速的看出潜在的问题
- 代码提示的友好程度比较好
- 代码语义更清晰易懂
安装编译环境
需要node
环境
首先安装typescript
cnpm install -g typescript
编译项目的命令
tsc demo.ts
快速得到结果的方式:
全局安装ts-node
cnpm install -g ts-node --save
直接运行的命令
ts-node demo.ts
基础类型
number
类型和其他语言的int
类型差不多
案例
let b: number = 123; // => let b = 123; 指定了b的类型为number
对比js
let b = 123; // 没有指定b的类型
接口对象类型
interface Point {
x: number,
y: number
}
const point: Point = {
x: 3,
y: 4
}
对象类型
// 对象类型
const teacher: {
age: number,
name: string
} = {
age: 25,
name: 'Dell'
}
demo2.ts
// 基础类型 null、undefined、symbol、boolean、void
const count: number = 123;
const teacherName: string = 'Dell';
// 对象类型
const teacher: {
age: number,
name: string
} = {
age: 25,
name: 'Dell'
}
// numbers的类型是一个数组,里面每个类型都是number
const numbers: number[] = [1, 2, 3];
class Person {
}
// dell必须是一个Person类的对象
const dell: Person = new Person();
// getTotal是函数名,返回值是number
const getTotal: () => number = () => {
return 123;
}
type annotation
:类型注解,我们来告诉TS变量是什么类型
type intference
:类型推断,TS会自动的尝试分析变量的类型
demo3.ts
/**
* 此时firstNumber和secondNumber是任意类型,需要指定类型
* @param firstNumber
* @param secondNumber
*/
function getTotal(firstNumber: number, secondNumber: number) {
return firstNumber + secondNumber;
}
const total = getTotal(1, 2);
console.log(total);
const obj = {name: 'dell', age: 18}
函数的使用
函数的三种写法
function () {}
const hello1 = function () { }
const hello2 = () => { }
函数也需要确定返回值类型
几个特别的返回值类型
void
: 没有返回值never
:代表函数不可能执行完,通常在异常和死循环中出现
functiondemo.ts
function add(first: number, second: number): number {
return first + second;
}
const hello1 = function () {
}
const hello2 = () => {
}
const total = add(1, 2);
/**
* 函数的返回值是void,没有返回值
*/
function sayHello(): void {
console.log('hello');
}
/**
* 函数不可能执行完成使用never
*/
function errorEmitter(): never {
while (true) {
}
}
/**
* 解构
* @param first
* @param second
*/
function add1({first, second}: { first: number, second: number }): number {
return first + second;
}
const totals = add1({first: 1, second: 2});
function getNumber({first}: { first: number }) {
return first;
}
const count = getNumber({first: 1});
接口类型
- interface 和 type 相类似,但并不完全一致
- interface 可以进行继承
- 接口可以定义一个函数类型
实质上大多数和
Java
的差不多,换了个说法,还是看代码解释
interfacedemo.ts
// 接口
interface Person {
name: string; // readonly 只读属性
age?: number; // age 可有可无
[propName: string]: any; // 其他属性 任何类型
say(): string;
}
interface Teacher extends Person {
teach(): string;
}
// 接口可以定义一个函数类型
interface sayHi {
(word: string): string
}
const say: sayHi = (word: string) => {
return 'sayHi';
}
const getPersonName = (person: Person): void => {
console.log(person.name);
}
const setPersonName = (person: Person, name: string): void => {
person.name = name;
}
const person = {
name: 'dell',
sex: 'male',
say(): string {
return 'say hello';
}
}
getPersonName(person);
setPersonName(person, 'lee');
getPersonName(person);
/**
* 类应用一个接口
*/
class User implements Person {
name = 'dell';
say(): string {
return 'say hello world';
}
}
类
定义:
class 类名(首字母肯定是大写的)
定义大多数都一样
类的属性和方法基本也和别的语言无差,但是就是会有类型的带入感
类的继承关键字也是
extends
字类调用父类的方法也是使用
super
关键字
super的使用场景:
当字类覆盖父类的方法之后,如果还想使用父类的方法就可以使用
super
来调用
案例代码:
class Person {
username = 'dell';
getName() {
return this.username;
}
}
const person = new Person();
console.log(person.getName());
/**
* 类的继承
*/
class Teacher extends Person {
getTeacherName() {
return 'teacher';
}
getName(): string {
return super.getName() + 'lee';
}
}
const teacher = new Teacher();
console.log(teacher.getName());
console.log(teacher.getTeacherName());
执行ts-node classdemo.ts
的输出结果:
dell
delllee
teacher
访问类型
关键字:
- private:只允许我在类内部使用
- protected:允许在类内及继承的子类中使用
- public:允许在类的内外被调用
构造器
就是其他语言的构造方法
用法差不多都一样
案例1
传统写法
class Person {
private name: string;
/**
* 构造器
* @param name
*/
constructor(name: string) {
this.name = name;
}
}
const person = new Person('dell');
案例2
简化写法
class Person {
/**
* 构造器
* @param name
*/
constructor(public name: string) {}
}
const person = new Person('dell');
与上面的案例1等价
父类的构造器里有内容
子类继承父类的时候,必须调用父类的构造方法
父类构造器没有参数的时候,子类也要调用
super()
方法
class Person {
constructor(public name: string) {
}
}
class Teacher extends Person {
constructor(public age: number) {
super('dell');
}
}
const teacher = new Teacher(28);
Getter/Setter方法
类中的属性为
private
时,外部实例化之后无法调用类内的属性,这时候需要get
方法进行获取
这里的私有属性一般写法为前面加个_
加属性名称
class Person {
constructor(private _name: string) {
}
get name(): string {
return this._name
}
set name(value: string) {
this._name = value
}
}
const person = new Person('dell');
console.log(person.name);
单例模式
- 限制外部使用
new
来新建实例 =>private constructor(){}
- 在类中添加
getInstance()
方法,用static
修饰,直接挂载到类上,而不是在类的实例上- 定义一个
private static instance: Demo
属性,直接属于类,又是私有属性,用来存储new Demo()
- 判断
instance
是否是undefined
然后进行new Demo()
- 如果存在,就直接返回已经有的
instance
class Demo {
private static instance: Demo
private constructor(public name: string) {
}
static getInstance() {
if (!this.instance) {
this.instance = new Demo('dell');
}
return this.instance;
}
}
// demo1 和 demo2 现在是一样的,这样构成了一个单例模式
const demo1 = Demo.getInstance();
const demo2 = Demo.getInstance();
console.log(demo1.name);
console.log(demo2.name);
调用流程
readonly修饰器
给类的属性里加个
readonly
之后,实例化后的类就无法进行赋值,只能读
抽象类
不多说,还是和其他静态类的语言差不多
abstract class Geom {
width: number;
abstract getArea(): number;
}
class Circle extends Geom {
getArea() {
return 123;
}
}