全国旗舰校区

不同学习城市 同样授课品质

北京

深圳

上海

广州

郑州

大连

武汉

成都

西安

杭州

青岛

重庆

长沙

哈尔滨

南京

太原

沈阳

合肥

贵阳

济南

下一个校区
就在你家门口
+
当前位置:首页  >  技术干货

15个Typescript项目常用语法练习,学会它,90%的场景不害怕!(二)

发布时间:2022-07-14 16:16:00
发布人:syq

  1.泛型 generics

/* 泛型 generics */

type UseState = <T>(v: T) => [T, (v: T) => void];

const useState: UseState = (v) => {
 return [
   v,
  (v) => {
     //...
  }
];
};

export const Component = () => {
 const [num, setNum] = useState(0); // OK
 const [str, setStr] = useState(""); // OK
 const [list, setList] = useState([1, 2, 3]); // OK

 // test
 const newNum = num + 1;
 setNum(newNum);

 const newStr = str.toUpperCase();
 setStr(newStr);

 const newList = list.slice(1);
 setList(newList);
};

Typescript项目常用语法

  2.部分对象 Partial

/* 部分对象 Partial */

interface User {
  name: string;
  age: number;
  occupation: string;
}

export const users: User[] = [
  {
    name: "Max Mustermann",
    age: 25,
    occupation: "Chimney sweep"
  },
  {
    name: "Wilson",
    age: 23,
    occupation: "Ball"
  }
];

type Criteria = {
  [Property in keyof User]?: User[Property];
};

// 等同于
// type Criteria = Partial<User>;

export const filterUsers = (users: User[], criteria: Criteria): User[] =>
  users.filter((user) => {
    const criteriaKeys = Object.keys(criteria) as (keyof Criteria)[];
    return criteriaKeys.every((fieldName) => {
      return user[fieldName] === criteria[fieldName];
    });
  });

const usersOfAge23 = filterUsers(users, {
  age: 23
});

  3.函数中 this 的使用

/* 函数中 this 的使用 */
// 参考 https://www.typescriptlang.org/docs/handbook/2/functions.html#declaring-this-in-a-function

export const debounce = <F extends (...args: any[]) => void>(
  fn: F,
  delay = 200
) => {
  let timeout = 0;
  return function (this: any, ...args: any[]) {
    timeout && clearTimeout(timeout);
    timeout = window.setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  } as F;
};

  4.类型编程-从基础类型构造新类型

/* 类型编程-从基础类型构造新类型 */

export type CustomObject<K extends string | number, T> = { [key in K]: T };

// 1. 示例
// ObjectOfStringValue 对象的值只能为字符串类型
type ObjectOfStringValue = CustomObject<string, string>;
const objOfStringValue: ObjectOfStringValue = {
  h: "hello", // OK
  w: "world" // OK
};

// 2. ObjectOfStringValue
// ObjectOfStringValue 对象的值只能为数字类型
type ObjectOfNumberValue = CustomObject<string, number>;
const objOfNumberValue: ObjectOfNumberValue = {
  a: 100, // OK
  b: 100 // OK
};
const a = objOfNumberValue.a;

// 3. ObjectOfUserValue
type User = {
  username: string;
  age: number;
};

// ObjectOfUserValue 对象的值只能为User类型
type ObjectOfUserValue = CustomObject<string, User>;

const objOfUserValue: ObjectOfUserValue = {
  u1: {
    username: "xiaoming",
    age: 18
  }
};
const { username } = objOfUserValue.u1;

  5.对象类型的继承

/* 对象类型的继承 */

export interface Response {
  data: any;
  status: number;
  statusText: string;
}

// 1. Response 类型的基础上添加 config 属性
export interface ResponseWithConfig extends Response {
  config: any;
}
const responseWithConfig: ResponseWithConfig = {
  data: 100,
  status: 0,
  statusText: "success",
  config: {}
};

// 2. Response 类型的基础上改写 data 属性类型
export interface StringResponse extends Response {
  data: string;
}
const stringResponse: StringResponse = {
  data: "100",
  status: 0,
  statusText: "success"
};

  6.对象类型的修改

/* 对象类型的修改 */
/* extends可以继承对象类型,但不可与原类型冲突,此时可以先使用 Omit 去除需要修改的属性 */

export interface TreeNode {
  id: number;
  value: number;
  children?: TreeNode[];
}

// 1. 去除 TreeNode id 属性同时修改 children 属性的类型
export interface NodeWithoutId extends Omit<TreeNode, "id" | "children"> {
  children?: NodeWithoutId[];
}

// OK
const nodeWithoutId: NodeWithoutId = {
  value: 1,
  children: [
    {
      value: 2
    }
  ]
};

  7.类型编程-条件判断

/* 类型编程-条件判断 */

export declare type Person<T extends "User" | "Admin"> = T extends "User"
  ? {
      username: string;
    }
  : {
      username: string;
      role: string;
    };

const user: Person<"User"> = { username: "xiaoming" }; // OK

const admin: Person<"Admin"> = { username: "xiaofang", role: "manager" }; // OK

  8.React 组件 Props 范型

/* React 组件 Props 范型 */

import { useState } from "react";

// value 可为字符串或数字
type Value = number | string;
interface Props<T extends Value> {
  value?: T;
  onChange?: (v: T) => void;
  type?: "number" | "text";
}

const Input = <T extends Value>({
  value,
  onChange,
  type = "text"
}: Props<T>) => {
  return (
    <input
      value={value}
      onChange={(e) => {
        const { value } = e.target;
        onChange?.((type === "number" ? parseInt(value, 10) : value) as T);
      }}
      type={type}
    />
  );
};

// test
const Test = () => {
  const [num, setNum] = useState(0);
  const [str, setStr] = useState("");

  return (
    <div>
      <Input value={num} onChange={(v) => setNum(v)} type="number" />
      <Input value={str} onChange={(v) => setStr(v)} />
    </div>
  );
};

export default Input;

  更多关于前端培训的问题,欢迎咨询千锋教育在线名师,如果想要了解我们的师资、课程、项目实操的话可以点击咨询课程顾问,获取试听资格来试听我们的课程,在线零距离接触千锋教育大咖名师,让你轻松从入门到精通。

相关文章

Arduino和单片机区别?

Arduino和单片机区别?

2023-10-14
什么是PlatformIo?

什么是PlatformIo?

2023-10-14
文件扩展名(后缀名)是什么?

文件扩展名(后缀名)是什么?

2023-10-14
云快照与自动备份有什么区别?

云快照与自动备份有什么区别?

2023-10-14

最新文章

常见网络安全面试题:Windows常用的命令有哪些?

常见网络安全面试题:Windows常用的命令有哪些?

2023-10-09
常见网络安全面试题:根据设备告警如何展开排查?

常见网络安全面试题:根据设备告警如何展开排查?

2023-10-09
常见网络安全面试题:mysql加固呢?(数据库加固)

常见网络安全面试题:mysql加固呢?(数据库加固)

2023-10-09
常见网络安全面试题:windows和linux加固?(操作系统加固)

常见网络安全面试题:windows和linux加固?(操作系统加固)

2023-10-09
在线咨询 免费试学 教程领取