Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript 各个击破 #16

Open
ZhenHe17 opened this issue Dec 13, 2019 · 0 comments
Open

TypeScript 各个击破 #16

ZhenHe17 opened this issue Dec 13, 2019 · 0 comments

Comments

@ZhenHe17
Copy link
Owner

ZhenHe17 commented Dec 13, 2019

Type 和 Interface 的区别

本节摘自 Typescript: Interfaces vs Types

1. 对于对象和函数

type 和 interface 都可以用来定义对象和函数的类型,区别是语法不同

Interface

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

interface SetPoint {
  (x: number, y: number): void;
}

Type

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

type SetPoint = (x: number, y: number) => void;

2. 对于其他类型

相比 interface,type 还可以用于定义 原始类型、联合类型和元组。

// primitive 原始类型
type Name = string;

// object 对象
type PartialPointX = { x: number; };
type PartialPointY = { y: number; };

// union 联合类型
type PartialPoint = PartialPointX | PartialPointY;

// tuple 元组
type Data = [number, string];

3. 继承

两者都可以被继承,只是语法不同。并且 type 可以继承 interface,interface 也可以继承 type。

// Interface 继承 interface
interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }

// type 继承 type
type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };

// Interface 继承 type
type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }

// type 继承 interface
interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

4. 实现

类实现 interface 或者 type 用的是一样的语法,但是类不能实现一个联合类型的type。

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

class SomePoint implements Point {
  x: 1;
  y: 2;
}

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

class SomePoint2 implements Point2 {
  x: 1;
  y: 2;
}

type PartialPoint = { x: number; } | { y: number; };

// 错误的代码: 不能实现联合类型
class SomePartialPoint implements PartialPoint {
  x: 1;
  y: 2;
}

5. 合并声明

不同于 type,interface 可以声明多次,多次声明同一个 interface 会将他们合并。

// 声明了两次 Point 最终等同于:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };

泛型

先看看使用泛型的语法:

function identity<T>(arg: T): T {
    return arg;
}

我们给identity添加了类型变量T。 T帮助我们捕获用户传入的类型(比如:number),之后我们就可以使用这个类型。 之后我们再次使用了 T当做返回值类型。现在我们可以知道参数类型与返回值类型是相同的了。 这允许我们跟踪函数里使用的类型的信息。

可以看出,泛型实际上是用类型变量记录了传入的类型。每次传入不同类型的参数,其类型也得以保存。下面是官方文档里比较复杂的例子:

// 一个更高级的例子,使用原型属性推断并约束构造函数与类实例的关系。
class BeeKeeper {
    hasMask: boolean;
}

class ZooKeeper {
    nametag: string;
}

class Animal {
    numLegs: number;
}

class Bee extends Animal {
    keeper: BeeKeeper;
}

class Lion extends Animal {
    keeper: ZooKeeper;
}

function createInstance<A extends Animal>(c: new () => A): A {
    return new c();
}

createInstance(Lion).keeper.nametag;  // typechecks!
createInstance(Bee).keeper.hasMask;   // typechecks!

在 React 里使用 TS

用 TS 开发 React 时先要注意以下几点:

摘自深入理解 TypeScript

  • 使用文件后缀 .tsx(替代 .ts);
  • 在你的 tsconfig.json 配置文件的 compilerOptions 里设置选项 "jsx": "react";
  • 在你的项目里为 JSX 和 React 安装声明文件:npm i -D @types/react @types/react-dom;
  • 导入 react 到你的 .tsx 文件(import * as React from 'react')。

定义 React 组件

用类型 React.FunctionComponent<Props> 定义函数式组件:

type Props = {
  foo: string;
};

const MyComponent: React.FunctionComponent<Props> = props => {
  return <span>{props.foo}</span>;
};

<MyComponent foo="bar" />;

用类型 React.Component<Props,State> 定义类组件:

type Props = {
  foo: string;
};

class MyComponent extends React.Component<Props, {}> {
  render() {
    return <span>{this.props.foo}</span>;
  }
}

<MyComponent foo="bar" />;

用类型 React.ReactNode 定义可渲染的 React 内容:

type Props = {
  header: React.ReactNode;
  body: React.ReactNode;
};

class MyComonent extends React.Component<Props, {}> {
  render() {
    return (
      <div>
        {this.props.header}
        {this.props.body}
      </div>
    );
  }
}

<MyComponent header={<h1>Header</h1>} body={<i>body</i>} />

Hooks

useState

const [user, setUser] = React.useState<IUser | null>(null);

useRef

const ref2 = useRef<HTMLElement | null>(null);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant