1、花括号对象通过方括号字符串形式取值
let obj = { name: 'asd', age: 21, salary: 400, desc: "asdasd", op: ['asd', 'as', 'qwe'] };
for (let i in obj) {
console.log(obj[i as keyof typeof obj]);
}
let key = 'name';
console.log(obj[key as 'name']);
console.log(obj[key as keyof typeof obj]);
2、泛型约束
// 函数泛型约束
interface limit<Y> {
value: Y[];
length: () => number;
join: (str?: Y) => Y;
}
// 对T约束
function fun<Y, T extends limit<Y>>(params: T): Y {
let res: Y = params.join();
return res;
}
// 定义对象类型
type Obj1Type = {
value: string[],
length: () => number,
join: (v1?: string) => string
};
// 定义对象
const obj1: Obj1Type = {
value: ['123', '456'],
length() {
return this.value.length;
},
join() {
return this.value.join('');
}
};
const result1 = fun<string, Obj1Type>(obj1);
console.log(result1);
3、枚举
enum Fruits {
Apple,
Orange,
Banana,
Peach,
Pear,
Watermolen
}
console.log(typeof Fruits[0], Fruits.Banana);// string, 2
enum Fruits2 {
Apple = '123',
Orange = 'asd',
Banana = '123t',
Peach = '123d',
Pear = 'asd',
Watermolen = 'dasd'
}
console.log(Fruits2.Banana);// 123t
enum Fruits3 {
Apple = 10,
Orange,
Banana,
Peach = '123d',
Pear = 'asd',
Watermolen = 'dasd'
}
console.log(Fruits3[10], Fruits3.Banana);// Apple,12
4、抽象类
abstract class Virtual {
abstract name: string;
abstract work(): void;
}
class Human {
}
class Man extends Human implements Virtual {
name;
constructor(name: string) {
super();
this.name = name;
}
work() {
}
}
let m1 = new Man('Tom');
5、函数重载
// 函数重载
function handleData(x: string): string[];
function handleData(x: number): string;
function handleData(x: any): any {
if (typeof x === 'string') {
return x.split(' ');
} else if (typeof x === 'number') {
return String(x);
} else {
return 'error!';
}
}
console.log(handleData(3),handleData('as asdd asd 34'));
6、interface定义class的类型,interface继承
class Geometry {
setAttribute() {
}
}
//继承后 BoxGeometryType 要实现 Geometry的属性和方法
interface BoxGeometryType extends Geometry {
width: number;
height: number;
depth: number;
clone:()=>void;
}
class BoxGeometry implements BoxGeometryType {
width;
height;
depth;
constructor(width: number, height: number, depth: number) {
this.width = width;
this.height = height;
this.depth = depth;
}
clone(){
}
setAttribute() {
}
}
7、构造函数的定义、继承
interface FatherType {
name: string
age: number;
salary: number;
print: () => void;
getName: Function;
};
function Father(this: FatherType, name: string, age: number, salary: number) {
this.name = name;
this.age = age;
this.salary = salary;
this.print = function () {
console.log(this.name, this.age, this.salary);
}
}
Father.prototype.getName = function () {
console.log(this.name);
}
interface SonType extends FatherType {
name: string;
getName: Function;
father: () => void;
};
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son;
function Son(this: SonType, name: string, father: { name: string, age: number, salary: number }) {
Father.call(this, father.name, father.age, father.salary);
this.name = name;
}
Son.prototype.getName = function () {
console.log(this, this.name);
}
Son.prototype.father = function () {
console.log(this);
}
const son = new (Son as any)("Tom", { name: "Tom1", age: 21, salary: 123123 });
son.father();
son.getName();
export default {};
8、修饰器
在修饰器有:类修饰器、方法修饰器、参数修饰器、属性修饰器。
执行顺序:属性>方法>参数>类 。
1、类修饰器,可以在类上添加一些属性和方法
// example 1
const MessageDecorator: ClassDecorator = (target: Function) => {
target.prototype.message = (msg: string) => {
console.log(msg)
}
}
@MessageDecorator
class Login {
public login() {
(this as any).message('登录成功');
(<any>this).message('登录成功');
}
}
new Login().login();
// example 2
function Decorate(type: string) {
if (type == '1') {
return (target: Function) => {
console.log(target);
target.prototype.p0 = () => {
console.log('p1');
}
}
} else {
return (target: Function) => {
target.prototype.p0 = () => {
console.log('p2');
}
}
}
}
@Decorate('1')
class P1 { }
@Decorate('2')
class P2 { }
const pa = new P1();
const pb = new P2();
(pa as any).p0();
(<any>pb).p0();
2、 方法修饰器,可以修改被调用的函数,或者在被调用的函数调用前后做一些事情。
// example 1
const showDecorator:MethodDecorator=(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor)=>{
// 修改show函数
descriptor.value=()=>{
console.log('function changed.');
}
// 在外部不可以改
// descriptor.writable=false;
}
class User{
@showDecorator
public show(){
console.log('show???');
}
}
const u1=new User();
u1.show();
// example 2
const sleep = (time: number): MethodDecorator => {
return (...args: any[]) => {
const [, , descriptor] = args;
// 保存原函数
const method = descriptor.value;
console.log('first');
descriptor.value = () => {
setTimeout(() => {
// 在此处调用原函数
method();
}, time);
}
}
}
class Sleep {
@sleep(1000)
public show() {
console.log('print something out.');
}
}
new Sleep().show();
3、属性修饰器,可以用来控制类中属性的获取和修改
// example 1
const property: PropertyDecorator = (target: object, propertyKey: string | symbol) => {
let value:string;
Object.defineProperty(target,propertyKey,{
get:()=>{
return value.toLowerCase();
},
set:(v)=>{
value=v;
}
});
}
export class Hd {
@property
public title?: string | undefined ='123';
public show(value) {
this.title=value;
}
}
const h=new Hd()
h.show("abcHAGKSDJkjnas");
console.log(h.title)
// example 2
import 'reflect-metadata'
function Inject(target: any, key: string) {
// 根据A的类型进行实例化,并赋值到a,'design:type'自动获取固定名称,不需要自己defineMetadata
target[key] = new (Reflect.getMetadata('design:type', target, key))();
}
class A{
sayHello(){
console.log('hello');
}
}
class B {
@Inject
a!: A;
say() {
this.a.sayHello();
}
}
new B().say();
4、 参数修饰器,一般与方法修饰器配合使用,在调用类方法前,对方法参数进行提前处理。
导入import 'reflect-metadata'可以在修饰器之间进行传值
Reflect.defineMetadata('required', requiredParams, target, propertyKey);// 发送
let pArray=Reflect.getMetadata('required', target, propertyKey); // 接收
import 'reflect-metadata'
const params: ParameterDecorator = (target: object, propertyKey: string | symbol, parameterIndex: number) => {
let requiredParams: number[] = [];
requiredParams.push(parameterIndex);
Reflect.defineMetadata('required', requiredParams, target, propertyKey)
}
const validate: MethodDecorator = (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
console.log( 'method decorate params =',target, propertyKey,descriptor);
let pArray=Reflect.getMetadata('required', target, propertyKey);
console.log(pArray);
const method=descriptor.value;
descriptor.value=(...args)=>{
console.log('args=',args,'pArray=',pArray);
for(let i in pArray){
args[pArray[i]]+='!!!';
}
method(...args);
}
}
export class User {
@validate
public find(@params name: string,age:number) {
console.log(name,age);
}
};
new User().find("abcdef",21); // abcdef!!! 21!!!