TypeScript基本使用

68 阅读5分钟

TypeScript常见用法

//////////////////////////////////////////////// 常用
const a: boolean = true;
const b: number = 1;
const c: string = "s";
const d: undefined = undefined;
const e: null = null;
const f: number = 1;
const g: object = {};
const h: any = "any type";

//////////////////////////////////////////////// 数组
let list: number[] = [1, 2, 3];

//////////////////////////////////////////////// 元组
let x: [string, number, boolean];
x = ["hello", 10, false];

// void: 没有返回值
function warnUser(): void {}

//////////////////////////////////////////////// never
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
  throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
  return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
  while (true) {}
}

//////////////////////////////////////////////// 类型断言
// 类型断言有两种形式。
// 其一是“尖括号”语法:
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

// 另一个为as语法:
let someValue2: any = "this is a string";
let strLength2: number = (someValue as string).length;

//////////////////////////////////////////////// 联合类型
let gender: "男" | "女";
gender = "女";

//////////////////////////////////////////////// 枚举
enum Color {
  Red,
  Green,
  Blue,
}
let color: Color = Color.Green;

//////////////////////////////////////////////// 自定义类型
type Gender = "男" | "女";
type User = {
  name: string;
  age: number;
  gender: Gender;
};
let u: User;
u = {
  name: "sdfd",
  gender: "男",
  age: 34,
};

//////////////////////////////////////////////// 重载
/**
 * 重载获取符合预期的结果
 * 得到a和b拼接的结果
 * @param a
 * @param b
 */
function combine(a: string, b: string): string;
function combine(a: number, b: number): number;
function combine(a: number | string, b: number | string): number | string {
  if (typeof a === "number" && typeof b === "number") {
    return a * b;
  } else if (typeof a === "string" && typeof b === "string") {
    return a + b;
  }
  throw new Error("a和b必须是相同的类型");
}

const result = combine("1", "2");
const result2 = combine(1, 2);

//////////////////////////////////////////////// 接口
interface User2 {
  name: string;
  age: number;
  sayHello(): void;
}

const user: User2 = {
  name: "fx",
  age: 28,
  sayHello() {},
};

let Log = console.log;

let arsg1: boolean = true;
let args2: number = 110;
let args3: string = "hello, ts";
let args4: null = null;
//在 TypeScript 中,可以使用 null 和 undefined 来定义这两个原始数据类型:
//与 void 的区别是,undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给 number 类型的变量:
let args5: undefined = undefined;
//声明一个 void 类型的变量没有什么用,因为你只能将它赋值为 undefined 和 null【null好像不行】
let args6: void = undefined;
let args7: any = "any"; //任意值
let args8: any[] = [1, "2", true, null, Symbol("fux"), undefined, { a: "a" }];
let grgs8_1: Array<any> = [
  1,
  "2",
  true,
  null,
  Symbol("fux"),
  undefined,
  { a: "a" },
];
let args9 = "seven"; //TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论。
let args10; //如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:
args10 = "F";
args10 = 123;
let args11: string | number | boolean; //联合类型  变量在被赋值的时候,会根据类型推论的规则推断出一个类型:
args11 = 11;
args11 = "33";
args11 = true;
let args12: any[] = [1, 2, "3", true, Symbol("fux"), new Date(), [1, 1, 1]]; //定义数组类型
let args13: Array<number> = [1, 2, 3]; //数组泛型
// let args13:number[]= [1,2,3]  //数组泛型§
// §
//args14展示了类数组
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

function getLength(something: string | number): string {
  return something.toString();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

//可用于对类的一部分行为进行抽象以外,也常用于对「对象的形状(Shape)」进行描述
interface Person {
  readonly id: number; //只读属性 注意,只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候:
  name: string;
  [props: string]: any; //任意 一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:
}

let obj1: Person = {
  id: 2,
  name: "fx",
  age: 22,
  height: "170cm",
  weight: "80kg",
};

// let args14:Person[] = [obj1]
let args14: Array<Person> = [obj1];

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

function fun1(x: number, y: number): number {
  return x + y;
}

let fun2 = function (x: number, y: number): number {
  return x + y;
};

const add = (x: number, y: number, z?: number): number => {
  if (typeof z === "number") {
    return x + y + z;
  }
  return x + y;
};

const add2: (x: number, y: number, z?: number) => number = add;

//定义函数
interface ISum {
  (x: number, y: number, z?: number): number;
}

const add3: ISum = add;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//泛型约束§
function echo<T>(arg: T): T {
  console.log(arg);
  return arg;
}
let res = echo(12);

function echo2<T>(arg: T[]): T[] {
  console.log(arg.length);
  return arg;
}
let res2 = echo<Array<number>>([1, 2, 3]);

//泛型约束
interface IEeho {
  length: number;
}
function echo3<T extends IEeho>(arg: T): T {
  console.log(arg.length);
  return arg;
}
let res3 = echo({ length: 10 });
// let res3 = echo([])

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//用接口定义函数的形状§
interface SearchFn {
  (data: string[], keyword: string): boolean;
}

let mySearch: SearchFn = function (data: string[], keyword: string) {
  return data.filter((l) => l === keyword).length > 0;
};

///////可选参数,可选参数后面不允许再出现必需参数了:
///////参数默认值§
function buildStr(fistStr: string = "fux", str2?: string[], str3?: string) {
  let append = fistStr;
  if (str2) {
    str2.map((l) => (append += l));
  }
  if (str3) {
    append += str3;
  }

  return append;
}

///////剩余参数§
function buildStr2(fistStr: string = "fux", ...arr: any[]) {
  let append = fistStr;
  arr.forEach((element) => {
    append += element;
  });
  return append;
}

/////////重载§
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string | void {
  if (typeof x === "number") {
    return Number(x.toString().split("").reverse().join(""));
  } else if (typeof x === "string") {
    return x.split("").reverse().join("");
  }
}

////////类型别名
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
  if (typeof n === "string") {
    return n;
  } else {
    return n();
  }
}
getName("1");
getName(() => "2");

//交叉
interface IName {
  name: string;
}
type IPerson = IName & { age: number };
let fux: IPerson = {
  name: "fux",
  age: 12,
};

//字面量
type Dirctions = "Up" | "Right" | "Down" | "Left";
let toWhere: Dirctions = "Down";

////////字符串字面量类型用来约束取值只能是某几个字符串中的一个。
type EventNames = "click" | "scroll" | "mousemove";
function handleEvent(ele: Element, event: EventNames) {
  // do something
}
handleEvent(document.getElementById("hello") as Element, "scroll"); // 没问题

////////数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。
let tom: [string, number, boolean] = ["Tom", 25, false];

//////////////泛型
function createArray<T>(length: number, value: T): Array<T> {
  let result: T[] = [];
  for (let i = 0; i < length; i++) {
    result[i] = value;
  }
  return result;
}

createArray<number>(3, 1); // 指定它具体的类型为number
createArray(3, "xxx"); //让类型推论自动推算出来:

function swap<T, U>(tuple: [T, U]): [U, T] {
  return [tuple[1], tuple[0]];
}
swap<number, string>([7, "seven"]); // ['seven', 7]
swap([7, 7]); // ['seven', 7]

function copyFields<T extends U, U>(target: T, source: U): T {
  for (let id in source) {
    target[id] = (<T>source)[id];
    // target[id] = (source as T)[id];
  }
  return target;
}

let x = { a: 1, b: 2, c: 3, d: 4 };

copyFields(x, { b: 10, d: 20, c: 11 });