TypeScript高级用法

摘要

TypeScript使用起来很麻烦,但是效果却很香!

一、类型复用不足

TypeScript允许我们使用typeinterface来定义类型。

type定义的类型可以通过交叉类型(&)来进行复用,而interface定义的类型则可以通过继承(extends)来实现复用。

复用type定义的类型:

type Point = {
  x: number;
  y: number;
};

type Coordinate = Point & {
  z: number;
};

复用interface定义的类型:

interface Point {
  x: number;
  y: number;
};

interface Coordinate extends Point {
  z: number;
}

interface复用type定义的类型:

type Point = {
  x: number;
  y: number;
};

interface Coordinate extends Point {
  z: number;
}

type复用interface定义的类型:

interface Point {
  x: number;
  y: number;
};

type Coordinate = Point & {
  z: number;
};

二、工具类型Omit与Pick

例如,有一个已有的类型Props需要复用,但不需要其中的属性c。在这种情况下,团队成员会重新定义Props1,仅包含Props中的属性ab,同时添加新属性e

interface Props {
  a: string;
  b: string;
  c: string;
}

interface Props1 {
  a: string;
  b: string;
  e: string;
}

我们可以利用TypeScript提供的工具类型Omit来更高效地实现这种复用。

interface Props {
  a: string;
  b: string;
  c: string;
}

interface Props1 extends Omit<Props, 'c'> {
  e: string;
}

工具类型Pick也可以用于实现此类复用。

interface Props {
  a: string;
  b: string;
  c: string;
}

interface Props1 extends Pick<Props, 'a' | 'b'> {
  e: string;
}

三、处理含有不同类型元素的数组

我们不知道如何定义含有不同类型元素的数组,通常会选择使用any[],但这会带来类型安全问题,元组是处理这种情况的理想选择。通过元组,我们可以在一个数组中包含不同类型的元素,同时保持每个元素类型的明确性。

function useMyHook(): [string, number] {
  return ['示例文本', 42];
}

function MyComponent() {
  const [text, number] = useMyHook();
  console.log(text);  // 输出字符串
  console.log(number);  // 输出数字
  return null;
}

四、处理参数数量和类型不固定的函数

通过函数重载,我们可以在同一函数名下定义多个函数实现,根据不同的参数类型、数量或返回类型进行区分。

function greet(name: string): string;
function greet(age: number): string;
function greet(value: any): string {
  if (typeof value === "string") {
    return `Hello, ${value}`;
  } else if (typeof value === "number") {
    return `You are ${value} years old`;
  }
}

对于箭头函数,虽然它们不直接支持函数重载,但我们可以通过定义函数签名的方式来实现类似的效果。

type GreetFunction = {
  (name: string): string;
  (age: number): string;
};

const greet: GreetFunction = (value: any): string => {
  if (typeof value === "string") {
    return `Hello, ${value}`;
  } else if (typeof value === "number") {
    return `You are ${value} years old.`;
  }
  return '';
};

五、组件属性定义

我们在定义组件属性时既可以使用type也可以使用interface

由于同名接口会自动合并,而同名类型别名会冲突,我推荐使用interface定义组件属性。这样,使用者可以通过declare module语句自由扩展组件属性,增强了代码的灵活性和可扩展性。

interface UserInfo {
  name: string;
}
interface UserInfo {
  age: number;
}

const userInfo: UserInfo = { name: "张三", age: 23 };

总结

做项目还是建议使用js,效率高。做产品推荐使用ts,精打细磨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zqwang888

一毛不嫌少,一块不嫌多!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值