typescript

1,694 阅读2分钟
sudo npm i typescript -g

# 生成配置文件
tsc --init

# tsc不加文件名会使用tsconfig.json中的配置
tsc

sudo npm i ts-node -g
# 会使用tsconfig.json中的配置
ts-node demo.ts

类型

interface

interface Student {
    age: number;
    sex?: string;
}
​
interface OldStudent extends Student {
    name: string
}
​
// 效果同extends
interface Student {
    name: string;
}

交叉类型

interface Student {
    age: number;
    sex?: string;
}
​
type OldStudent = Student && {name:string}

有属性的函数类型定义

interface FunctionWithAttributes {
    attr: string;
    (str: string): void;
}
​
const test: FunctionWithAttributes = (str: string) => {
    console.log(str);
}
test.attr = "attributes";

构造函数的类型定义

interface ClassWithConstructor {
    new(str: string): void;
}
function testOne(outerClase: ClassWithConstructor) {
    const instance = new outerClase("new");
}
class TestOne {
    name: string;
    constructor(str: string) {
        this.name = str;
    }
}
testOne(TestOne);

interface 中的 readonly 只读

interface Person {
    readonly name: string;
    age: number;
}
const dell: Person = { name: 'dell', age: 30 };
dell.age = 30;

readonly

class Person {
    public readonly name: string
    constructor(name: string) {
        this.name = name;
    }
}
const person = new Person('dell');
person.name = 'any';
console.log(person.name);

如何给对象扩展属性

interface ArrayObject {
    [key: string]: string | number | boolean;
    length: number
}
const obj: ArrayObject = {
    test: true,
    length: 0
}

extends 和泛型的结合,解决固定参数传递需求

interface Person {
    name: string;
}
​
function getName<T extends Person>(person: T) {
    return person.name;
}
​
getName({ name: 'dell', age: 30 })

对象类型继承

interface Animal {
    name: string;
    age: number;
    breath: () => void;
}
​
interface Dog extends Animal {
    bark: () => void;
}
​
const dog: Dog = {
    name: "dog",
    age: 1,
    breath: () => { },
    bark: () => { },
}

对象多继承

交叉类型也可实现多继承

interface Circle {
    radius: number;
}
​
interface Colorflu {
    color:number;
}
​
interface ColorfluCircle extends Circle,Colorflu{}

keyof

interface Teacher {
    name: string;
    age: number;
    sex: 'male' | 'female';
}
​
const teacher: Teacher = {
    name: 'Dell',
    age: 30,
    sex: 'male',
}
​
function getTeacherInfo<T extends keyof Teacher>(teacher: Teacher, key: T) {
    return teacher[key];
}

条件类型

interface IdLabel {
    id: number;
}
interface NameLabel {
    name: string;
}
​
/*
function createLabelOverload(key: string): NameLabel;
function createLabelOverload(key: number): IdLabel;
function createLabelOverload(key: string | number): IdLabel | NameLabel {
    if (typeof key === 'string') {
        return { name: key }
    }
    return { id: key }
}
const label = createLabelOverload('dell');
*/
​
type idOrNameLabel<T> = T extends number ? IdLabel : NameLabel;
​
function createLabel<T extends string | number>(key: T): idOrNameLabel<T>;
function createLabel(key: string | number): IdLabel | NameLabel {
    if (typeof key === 'string') {
        return { name: key }
    }
    return { id: key }
}
const labelA = createLabel(1);
type TypeOfMessage<T> = T extends { message: unknown } ? T['message'] : never;
interface Email {
    from: string;
    to: string;
    message: string;
}
​
const emailObject: Email = {
    from: 'dell@qq.com',
    to: 'lee@qq.com',
    message: 'hello lee',
}
​
const email: TypeOfMessage<Email> = 'hello lee';
type GetRetureType<T> = T extends (...args: never[]) => infer a ? a : never;
​
type example = GetRetureType<() => string>;
type example1 = GetRetureType<string>;
// [T] 把T看做一个整体
type ToArray<T> = [T] extends [any] ? T[] : never;
type StringOrNumberArray = ToArray<string | number>;
type NeverType = ToArray<never>;

基础映射类型

interface User {
    readonly name: string;
    readonly age: number;
    male?: boolean;
}
​
type FilterReadeOnly<T> = {
    - readonly [P in keyof T]-?: T[P];
}
​
type PublicUser = FilterReadeOnly<User>;
const publicUser: PublicUser = {
    name: 'dell',
    age: 30,
    male: true
}
publicUser.age = 33;

字面量语法 get${Capitalize<>}

interface User {
    name: string;
    age: number;
    male: boolean;
}
​
type GetPropertyFunctions<T> = {
    [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P];
}
​
type UserFunctionsType = GetPropertyFunctions<User>;

union 类型使用

type SquareEvent = {
    kind: 'square';
    x: number;
    y: number;
}
​
type CircleEvent = {
    kind: 'circle';
    radius: number;
}
​
type GenerateEventsFunctions<Events extends { kind: string }> = {
    [Event in Events as Event['kind']]: (event: Event) => number;
}
type NewType = GenerateEventsFunctions<SquareEvent | CircleEvent>;
/**
type NewType = {
    square: (event: SquareEvent) => number;
    circle: (event: CircleEvent) => number;
}
*/

class get set

class Person {
    constructor(private _name: string) { }
    get name() {
        return this._name + ' lee';
    }
    set name(name: string) {
        this._name = name;
    }
}
const person = new Person('dell');
console.log(person.name);
person.name = 'any';

单例

class Demo {
    private static instance: Demo;
    private constructor() { }
    static getInstance() {
        if (!this.instance) {
            this.instance = new Demo();
        }
        return this.instance;
    }
}

抽象类

abstract class Geom {
    width: number;
    getType() {
        return 'Gemo';
    }
    abstract getArea(): number;
}
​
class Circle extends Geom {
    getArea(): number {
        return 123;
    }
}

类型保护

interface Bird {
    fly: boolean,
    sing: () => {},
}
​
interface Dog {
    fly: boolean,
    bark: () => {},
}
​
// 类型断言
function trainAnial(animal: Bird | Dog) {
    if (animal.fly) {
        (animal as Bird).sing();
    } else {
        (animal as Dog).bark();
    }
}
​
// in 语法
function trainAnialSecond(animal: Bird | Dog) {
    if ('sing' in animal) {
        animal.sing();
    } else {
        animal.bark();
    }
}
​
// typeof 
function add(first: string | number, second: string | number) {
    if (typeof first === 'string' || typeof second === 'string') {
        return `${first}${second}`;
    }
    return first + second;
}
​
// instanceof 
class NumberObj {
    count: number
}
​
function addSecond(first: object | NumberObj, second: object | NumberObj) {
    if (first instanceof NumberObj && second instanceof NumberObj) {
        return first.count + second.count;
    }
    return 0;
}