1. 类型的注解和类型检查
let name = "xx"; // 类型推论
let title:string = "xxxx"; // 类型的注解和类型检查
//数组使用类型
let names:string [];
names = ['Tom']; // 或Array
let foo:any = 'xx';
foo = 3
// any类型也可以用于数组
let list:any[] = [1, true, 'xxxx'];
list[1] = 100;
// 函数中使用的类型注解
function greeting (person: string):string {
return 'Hello, ' + person
}
// void 类型, 常常用于没有返回值的函数
function warnUser():void {
alert('this is my warning message')
}
2. 函数
// 此处name 和 age 是必填参数
// 如果要变为可选参数加上?
// 可选参数在必选参数后面
function sayHello(name: string, age:number = 20, addr?:string): string {
return '你好: ' + name + ' ' + age
}
// 重载
// 参数数量量或者类型或者返回类型不不同函数名却相同
// 先声明,在实现
function info(a: { name: string }): string;
function info(a: string): object;
function info(a: { name: string } |string): any {
if (typeof a==="object") {
return a.name;
} else {
return { name: a };
}
console.log(info({ name: "tom" }));
console.log(info("tom"));
3. 类型推论
class MyComp {
private _foo: string; // 私有属性
private bar: string; // 保护属性
readonly mua = 'mua' // 只读属性必须在声明时或构造函数里初始化
// 构造函数: 初始化成员变量
// 参数加上修饰符, 能够定义并初始化一个成员属性
constructor (private tua = 'tua') {
this._foo = 'foo'
this.bar = 'bar'
}
// 方法也有修饰符
private someMethod() {}
// 存储器: 存储数据时可添加额外逻辑; 在vue里面可以用作计算属性
get foo() {return this._foo}
set foo(val) {this._foo = val}
}
vue应⽤用:声明⾃自定义类型约束数据结构,Hello.vue
// 定义⼀一个特性类,拥有更更多属性
class Feature {
constructor(public id: number, public name: string) {}
}
// 可以对获取的数据类型做约束
@Component
export default class HelloWorld extends Vue {
private features: Feature[];
constructor() {
super();
this.features = [
{ id: 1, name: "类型注解" },
{ id: 2, name: "编译型语⾔言" }
];
}
}
vue应⽤用:利利⽤用getter设置计算属性
get count() {
return this.features.length;
}
class是语法糖,它指向的就是构造函数。
class Person { // 指向构造函数
constructor(name, age) { // constructor 是默认方法, new 实例时自动调用
this.name = name; // 属性会声明在实例上, 应为this 指向实例
this.age = age;
}
say() { // 方法会声明在原型上
return '我的名字是' + this.name + '我今年' + this.age + '岁了'
}
}
console.log(typeof Person); // function
console.log(Person === Person.prototype.constructor); // true
// 等效于
function Person (name, name) {
this.name = name
this.age = age
}
Person.prototype.say = function() {
return '我的名字是' + this.name + '我今年' + this.age + '岁了'
}
4. 接口
interface,仅定义结构,不不需要实现
interface Person {
firstName: string;
lastName: string;
sayHello(): string // 要求实现方法
}
// 实现接口
class Greeter implements Person {
constructor(public firstName='', public lastName='') {}
sayHello() {
return 'hello, ' + this.firstName + ' ' this.lastName
}
}
// 面向接口编程
function greeting (person: Person) {
return person.sayHello()
}
// const user = {firstName: 'jane', lastName: 'user'}
const user = new Greeter('jane', 'user') // 创建对象实例
console.log(user);
console.log(greeting(user));
5. 泛型Generrics
Generics是指在定义函数、接⼝口或类的时候,不不预先指定具体的类型,⽽而在使⽤用的时候再指定类型的⼀一种特性。
// 定义泛型接口
interface Result {
ok: 0 | 1;
data: T[];
}
// 定义泛型函数
function getData(): Result {
const data: any[] = [
{id: 1, name: '类型注解', version: '2.0'},
{id: 1, name: '类型注解', version: '2.0'},
]
return {ok: 1, data};
}
// 使用泛型
this.features = getData().data;
返回Promise
function getData(): Promise> {
const data: any[] = [
{ id: 1, name: "类型注解", version: "2.0" },
{ id: 2, name: "编译型语⾔言", version: "1.0" }
];
return Promise.resolve>({ ok: 1, data });
}
使用
async created() {
const result = await getData();
this.features = result.data;
}
6. 装饰器
装饰器实际上是工厂函数,传入一个对象,输出处理后的新对象。
// 类装饰器器
@Component
export default class Hello extends Vue {
// 属性装饰器器
@Prop({ required: true, type: String }) private msg!: string;
// 函数装饰器器
@Watch("features", {deep: true})
onFeaturesChange(val: string, oldVal: any) {
console.log(val, oldVal);
}
// 函数装饰器器
@Emit('add')
private addFeature(event: any) {
const feature = {
name: event.target.value,
id: this.features.length + 1,
version: "1.0"
};
this.features.push(feature);
event.target.value = feature;
return event.target.value;
}
}
vuex使⽤用:vuex-class
安装
npm i vuex-class -S
定义状态,store.js
export default new Vuex.Store({
state: {
features: ['类型检测', '预编译']
},
mutations: {
addFeatureMutation(state: any, featureName: string){
state.features.push({id: state.features.length+1, name: featureName})
}
},
actions: {
addFeatureAction({commit}, featureName: string) {
commit('addFeatureMutation', featureName)
}
}
})
使用,Hello.vue
import { State, Action, Mutation } from "vuex-class";
@Component
export default class Feature extends Vue {
// 状态、动作、变更更映射
@State features!: string[];
@Action addFeatureAction;
@Mutation addFeatureMutation;
private addFeature(event) {
console.log(event);
// this.features.push(event.target.value);
this.addFeatureAction(event.target.value);
// this.addFeaturMutation(event.target.value);
event.target.value = "";
}
}
装饰器原理
装饰器器实际上是⼀一个函数,通过定义劫持,能够对类及其⽅方法、属性提供额外的扩展功能。
function log(target: Function) {
// target是构造函数
console.log(target === Foo); // true
target.prototype.log = function () {
console.log(this.bar);
}
// 如果类装饰器器返回⼀一个值,它会使⽤用提供的构造函数来替换类的声明。
}
// ⽅方法装饰器器
function dong(target: any, name: string, descriptor: any) {
// target是原型或构造函数,name是⽅方法名,descriptor是属性描述符,
// ⽅方法的定义⽅方式:Object.defineProperty(target, name, descriptor)
console.log(target[name] === descriptor.value);
// 这⾥里里通过修改descriptor.value扩展了了bar⽅方法
const baz = descriptor.value; // 之前的⽅方法
descriptor.value = function (val: string) {
console.log('dong~~');
baz.call(this, val);
}
return descriptor;
}
// 属性装饰器器
function mua(target, name) {
// target是原型或构造函数,name是属性名
console.log(target === Foo.prototype);
target[name] = 'mua~~~'
}
@log
class Foo {
bar = 'bar'
@mua ns!: string;
@dong
baz(val: string) {
this.bar = val
}
}
const foo2 = new Foo();
// @ts-ignore
foo2.log();
console.log(foo2.ns);
foo2.baz('lalala')
7. 更多详细说明看网站