类型
// 先指定类型,再赋值
let a: number;
a = 123;
// 指定类型后直接赋值
let b: String = 'hello';
// ts文件中直接指定值,ts会自动判断类型
let c = false;
// 给函数的参数和返回值指定类型
function sum(a: number, b: number): number{ // 第三个number表示返回值的类型
return a + b;
}
let a: 10; // 相当于一个常量,a只能是10
let b: number|String; // 联合类型,b可以是number类型,也可以是String类型
let c: 'hello'|'hi'; //c可以是hello,也可以是hi
let a: any; // a可以是任意类型
let c; // 没有指定,也是any
let b:string;
b = a; // 如果将any类型的a赋值给b,b也变成any类型,数据是不安全的
let a: unknown;
a = "asdf" // 这时a可以接收string类型
let c: string;
c = a; // 将不确定类型a赋值给c是会报错,因为类型不匹配,确保数据安全
// 如若想要赋值
let b = "hi"
if (typeof a === "string") {
b = a;
}
// 类型断言:unknown类型的e赋值给s时,指定s的的实际类型
s = e as string;
s = <string>e;
function fn2(): void{ // 返回值类型为空
}
// never: 表示永远不会返回结果;没有值,相当于Undefined
function fn3(): never{
throw new Error("报错了!");
}
// 声明一个object类型
let a:object;
// a就能是对象或函数
a = {};
a = function(){
};
a ={"asdf":'asdf', "pwd":'asdf'}
// {}表示传入的对象有两个属性,?表示age属性是可选的
let b: {name: string, age?:number};
b = {name: "孙悟空"}; // 赋值
// 错误写法
// let title={name:string, age:number};
// 这种方式比较重复,不采用
let c3: {name: string, a?:number, b?:number};
c3 = {name:"猪八戒", a:1, b:2}
//[propName: string]表示对象的属性名是string,后面的any表示任意类型
let c: {name: string, [propName: string]:any}
c = {name:"猪八戒", age: 18, gender: '男'} // 这样就能指定多个属性了
let d1: (a: number, b: number): number => a + b;
// 相当于
d1 = function (n1: number, n2: number): number {
return n1 + n2
}
// 数组的类型声明:
// 类型[]
// Array<类型>
let g1: string[];
g1 = ['a','b','c'];
let g2: Array<string>;
g2 = ['a','b','c'];
// 如下表示:当前数组只能由两个值,类型只能为字符串和数字
let h: [string, number];
h = ['hello', 123];
enum Gender{
Male = 0,
Female = 1,
}
let i: {name: string, gender: Gender};
i = {
name: '孙悟空',
gender: Gender.Male//'male'
}
// 类似字面量
type myType = 1 | 2 | 3 | 4 | 5;
let k: myType;
类
class Person{
// 定义属性
name: string = '孙悟空';
// static表示静态属性,readonly表示只读属性
static readonly age: number = 18;
// 方法
sayHello(){
console.log("Hello 大家好!")
}
// 静态方法
static sayHi(){
concole.log("hi!")
}
}
// new一个实例
const per = new Person();
// 赋值
per.name = 'tom';
console.log(per.name)
// 调用方法
per.sayHello();
// 通过类名调用静态方法
Person.sayHi()
构造函数
class Dog {
name: string;
age: number;
// 构造函数会在对象创建时调用
constructor(name: string, age: number) {
this.name = name,
this.age = age
}
bark(){
alert('汪汪汪!!');
console.log(this.name);
}
}
// 使用构造方法
const dog = new Dog('小黑', 4);
继承
// 父类
class Animal{
name: string;
age: number;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
sayHello(){
console.log('动物在叫!!');
}
}
// 子类继承父类后,会拥有父类的所有属性和方法
class Dog extends Animal{
// 子类中新增自己的方法
run(){
console.log(`${this.name}在跑啊~~`);
}
// 子类会覆盖父类中相同的方法
sayHello(){
console.log('汪汪汪!!');
}
}
super
// 父类
class Animal{
sayHello(){
console.log('动物在叫~~')
}
}
// 子类
class Dog extends Animal{
sayHello() {
// 在类的方法中 super就表示当前类的父类
super.sayHello();
console.log('汪汪汪~~')
}
}
抽象类
- 重点:抽象类的作用是使父类不能实例化,抽象方法用于重写
// 父类、抽象类,以abstract开头
abstract class Animal{
// 抽象方法
abstract sayHello():void;
}
// 子类
class Dog extends Animal{
// 重写抽象方法
sayHello() {
console.log('汪汪汪~~')
}
}
接口
interface myInterface{
name: string;
age: number;
}
interface myInterface{
gender: string;
}
const obj: myInterface = {
name: 'sss',
age: 111,
gender: '男'
};
// 接口
interface myInter{
name: string;
sayHello(): void;
}
// 实现类
class MyClass implements myInter{
name: string;
constructor(name: string){
this.name = name;
}
sayHello(){
console.log("大家好!");
}
}
属性封装
- 重点:属性使用private修饰时,修改该属性的值只能通过setter方法
// public 修饰的属性可以在任意位置访问(修改) 默认值
// private 私有属性, 私有属性只能在类内部进行访问(修改),通过在类中添加方法使得私有属性可以被外部访问
// protected 受保护的属性,只能在当前类和当前类的子类中访问(修改)
class Person {
public _name: string;
private _age: number;
constructor(name: string, age: number) {
this._name = name;
this._age = age;
}
// getter和setter方法
getName() {
return this._name;
}
setName(value: string) {
this._name = value;
}
getAge() {
return this._age;
}
setAge(value: number) {
if (value >= 0) {
this._age = value;
}
}
}
const per = new Person('孙悟空', 18);
per.setName('猪八戒');
per.setAge(-33);
class Person{
public _name: string;
private _age: number;
constructor(name: string, age: number) {
this._name = name;
this._age = age;
}
// TS中设置getter方法的方式
get name(){
console.log('get name()执行了!!');
return this._name;
}
set name(value:string){
this._name = value;
}
get age(){
return this._age
}
set age(value:number){
if(value >= 0){
this._age = value
}
}
}
// 创建对象
const per = new Person('孙悟空', 18);
per.name = '猪八戒';
per.age = -13
泛型
// 传入的参数类型与返回值类型可能不同
function fn(a: any):any {
return a;
}
// 如下函数中传入的参数类型与返回值类型相同
function fn<T>(a:T):T {
return a;
}
interface Inter{
length: number;
weidth: boolean;
}
// T extends Inter 表示泛型T是Inter子类
function fn3<T extends Inter>(a:T): number {
return a.length
}
class MyClass<T>{
name: T;
constructor(name:T){
this.name = name;
}
}
// new对象时指定类型
const mc = new MyClass<string>('孙悟空');