String string 区别

const msg: string = 'hello'; // 一般都写小写就ok了
const message: String = 'hello';
// 这个就代表这个文件是独立的模块, 就不会报在其他文件里重名的错误了
export {};

这边冒号后面的类型是区分开来的

  • strinig: 代表 ts 中的字符串类型
  • String: 代表 js 中字符串包装类的类型
  • let foo = 'cqc'; // 在默认情况下赋值, ts会自动将赋值的类型作为签名标识符的类型
    foo = 123456; // 这里会报错  Type 'number' is not assignable to type 'string'.
    

    数据类型 ( js 中存在的 )

    默认情况下如果可以推导出(infer)标识符的类型时候 一般不手动加类型

    数值 number
    //? number
    // ts 数值类型不区分 int float
    let num1: number = 213; // 普通数值
    let num2: number = 0b111; // 二进制
    let num3: number = 0o456; // 八进制
    let num4: number = 0x9ac; // 十六进制
    
    布尔 boolean
    // ? boolean
    let flag1 = 2 > 3;
    let flag2 = false;
    
    字符 string
    数组 Array
    // 一个数据中存放的元素类型应该是固定的
    // 注意这里是Array 不是 array
    const arr1: Array<string> = ['cqc']; // 不推荐(jsx 中冲突)
    const arr2: string[] = ['cqc']; // 推荐 效果同arr1
    
    对象 object
    // 可以赋默认值 自动推导
    const info1 = {
      name: 'cqc',
      age: 24,
    // 十分不推荐(使用info2.name的时候不会自动弹出提示 且报错 Property 'name' does not exist on type )
    const info2: object = {
      name: 'cqc',
    
    空值 null
    // null 类型只有一个 null 的值 只能赋值 null
    const nl: null = null; // null 类型时候最好手动指定下类型(否则类型自动推导是 any)
    
    未定义 undefined
    // 和 null 类型一样 只有一个值 只能赋值 undefined
    const und: undefined = undefined;
    
    唯一 symbol

    数据类型 ( ts 中独有的 )

    当进行一些类型断言的时候 as any 否则报错 在不想给某些 js 添加具体数据类型时候 any-script?

    const arr: any[] = [];
    
    unknown

    类似 any 类型, 用于不确定类型 在不能推导出来的时候使用 (可能是类型 a 可能是类型 b)

    unknown、any 区别

    unknown 类型的数据只能赋值给 unknown 类型 或者 any 类型, 但是 any 类型可以赋值任意类型

    let unknown1: unknown;
    let any1: any;
    const str1: string = any1;
    // ok
    const str2: string = unknown1;
    // Type 'unknown' is not assignable to type 'string'
    
    // 指定一个函数返回值类型 只能是 null || undefined
    const foo = function (str: string): void {
      return null || undefined;
    
    never

    表示一个函数永远不会发生值的类型

    const foo = function (): never {
      // while( true ) {};
      throw new Error();
    
    const handler = function (message: string | number) {
      switch (typeof message) {
        case 'string':
          break;
        case 'number':
          break;
        default:
          // 函数进入这里就会报错
          const check: never = message;
          break;
    // 这时候加入有人需要用 handler 函数处理其他类型, 那么他有可能在联合类型内加入他要处理的类型 比如:
    const handler = function (message: string | number | boolean) {...};
    // 这时候 handler 函数内没有处理到 boolean 这个新类型, switch 进入到 default 处理方式, 直接编译报错, 提醒人添加新类型的处理方式
    
    元组 tuple

    多种元素组合而成的数组

    const tupleInfo: [string, number, number] = ['cqc', 1.7, 170];
    // 应用场景
    // 希望调用一个函数 得到 [counter, setCounter]
    type MyFunction = <T>(state: T) => [T, (newValue: T) => void];
    const useState: MyFunction = function useState<T>(state: T) {
      let currentState = state;
      const changeState = (newState: T) => {
        currentState = newState;
      return [currentState, changeState];
    const [counter, setCounter] = useState(10);
    
    // 默认值 从 0 开始
    enum Direction {
      LEFT, // 0
      RIGHT, // 1
      TOP, // 2
      BOTTOM,
    function turnDirection(direction: Direction) {
      switch (direction) {
        case Direction.LEFT:
          // ...
          break;
        case Direction.RIGHT:
          // ...
          break;
        // ...
        default:
          break;
    turnDirection(Direction.RIGHT);
    // 可以自定义值
    enum DirectionMy {
      TOP = 10,
      BOTTOM = 20,
      LEFT, // 21 会取上面那个 + 1
    let d: DirectionMy = DirectionMy.TOP;
    enum DirectionMy1 {
      TOP = 'TOP', // 只可以是字符串
    
    泛型(重要)
    const foo = function <T, S>(typeT: T, typeS: S) {
      const tupleArr: [T, S] = [typeT, typeS];
      return tupleArr;
    // 接口中使用泛型
    interface IPerson<T1, T2 = number> {
      // T2 使用了默认类型
      name: T1;
      age: T2;
    const p: IPerson<string, number> = {
      name: 'cqc',
      age: 23,
    // 类中使用泛型
    class Point<T> {
      x: T;
      y: T;
      constructor(x: T, y: T) {
        this.x = x;
        this.y = y;
    const p = new Point('1.33', '2.22');
    const p1 = new Point<string>('1.33', '2.22');
    const p2: Point<string> = new Point('1.33', '2.22');
    // 普通数组中使用泛型
    const names: Array<string> = ['cqc']; // 不推荐
    
    泛型的限制
    interface ILength {
      length: number;
    interface IMy {
      name: string;
    const getLength: <T extends ILength & IMy>(arg: T) => number = function (arg) {
      return arg.length;
    getLength({ length: 3, name: 'cqc' });
    
    函数参数和返回值类型
    function sum1(n1: number, n2: number): number {
      return n1 + n2;
    const names = ['cqc', 'why', 'plo'];
    //匿名函数 item根据上下文的环境推导出来,可以不写注解
    names.forEach((item) => {
      item.length; // item: string
    // 定义常量时候
    type AddFnType = (...args: number[]) => number;
    const sum: AddFnType = (...args: number[]) => {
      return args.reduce((p, c) => p + c);
    sum(1, 2, 3, 1);
    
    type PrintType = {
      x: number;
      y: number;
      z?: number; // 可选类型  效果和 z: number | undefined 一样
    function printPoint(point: PrintType) {
      console.log(point.x);
      console.log(point.y);
      console.log(point.z);
    

    使用联合类型值时候, 需要小心该值的类型

  • 进行很多逻辑判断(类型缩小)
  • 返回值类型不能确定
  • function printID(id: number | string) {
    // 让传入的参数是可选的
    function foo(name?: string) {}
    
    type IDType = string | number | boolean;
    
    类型断言 as

    类型断言只允许转换为 更具体 或 不太具体的 类型, 防止不可能的强制转换

    // ? 类型断言 as
      默认这种方式获取的el 类型是 HTMLElement
      但是不同html标签属性不一样
      这时候可以使用类型断言
    const el = document.getElementById('img') as HTMLImageElement;
    el.src; // 在不使用类型断言时候 Property 'src' does not exist on type 'HTMLElement'
    // ---------
    class Person {}
    class Student extends Person {
      study() {}
    function satHi(p: Person) {
      // 这里知道p是 Student, 直接断言
      (p as Student).study();
    const stu = new Student();
    satHi(stu);
    // ----------
    // 不是特殊情况不推荐
    const message = 'hello';
    const num: number = message as number; // 报错
    const num: number = message as unknown as number; // 需要先断言 known 在断言 number, 才能赋值
    
    非空类型断言
    function printMessage(message?: string) {
      message!.toUpperCase(); // 这里加 ! 告诉ts编译器跳过对这部分的检查  但是调用该方法不传递参数 该报错还报错 printMessage()
    
    字面量类型

    字面量类型与他的值保持一致

    const message: 'cqc' = 'cqc';
    // 字面量类型的意义, 就是结合 联合类型 (和枚举类似)
    type Align = 'left' | 'center' | 'right';
    let align: Align = 'center';
    // ------------
    // 字面量推理
    type Method = 'POST' | 'GET';
    function request(url, method: Method) {}
    // 一般建议直接给 options 定死类型
    const option = {
      url: 'https:/.xxx/a',
      method: 'POST' as const, // 不加这个的话, 在调用 request 方法时候 这个属性类型会被定义 string, 加了后类型就是 POST
    request(options.url, options.method);
    
  • ?? 空值合并操作符
  • const a = false;
    const b = 'cqc';
    const res = a ?? b;
    // 当 a 为 null || undefined 时候, 返回右边值, 否则返回左侧值
    
  • 常见类型缩小方式
  • typeof
  • 平等缩小 ( === , !== )
  • instanceof // 实例(==new 出来的==) instanceof 原型
  • let a = xxx;
    // 缩小类型范围
    if(typeof a === 'string') {
    switch(..) {
    function printTime(time: string | Date) {
      if (time instanceof Date) {
        time.getTime()
    // instanceof -------------
    class Student {
      studing() {}
    class Teacher {
      teaching() {}
    function work(p: Student | Teacher) {
      if (p instanceof Student) {
      } else {
    

    函数名称相同,但是参数不同的几个函数 如果可以通过联合类型实现的函数重载, 直接联合类型 感觉函数重载比较鸡肋,最终函数逻辑的实现还是在一个函数体内去判断它的参数类型,然后做相应的操作。==ts 重载的作用,只是多了一个参数校验的功能==。

    // 编写一个add函数, 可以数字之间相加、也可以数字、字符串
    type AddType = number | string;
    function add(a1: number, a2: number): number; // 没有函数体
    function add(a1: string, a2: string): number;
    function add(n1: any, n2: any): any {
      if (typeof n1 === 'string' && typeof n2 === 'string') {
        return n1.length + n2.length;
      return n1 + n2;
    const res = add('20', '5');
    // 在函数重载中, 实现函数是不能直接被调用的
    // add([], 123); //No overload matches this call.
            摸鱼工程师
           
    粉丝