最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • TS是最好的语言(一)

    正文概述 掘金(missop)   2020-12-26   749

    TS是最好的语言(一)

    前言

    都快 2021 年了,TS 早就不是什么新技术,而是前端需要掌握的硬核知识,所以今天就从一些库入手开始探究 TS 的应用以及一些小技巧

    看本篇文章之前需要的一些基础知识:

    1. JS 基础知识
    2. 熟悉 react-router
    3. TS 官方文档至少看一遍,TS 的基本的类型了熟于心

    如果没有看过 TS 官方文档的话,可以先去看官方文档,也可以试玩一下 TS 编译器,链接如下:

    react-router

    从古老的用法开始:

    以前使用 react-router 中的 history 或者获取路由参数必须先将组件用 withRouter 包装,但是如果我们不声明 App 参数类型那么我们只能从参数中取到路由参数:

    // 示例一
    import React from "react";
    import { withRouter } from "react-router";
    const App = withRouter(({ history, match, a }) => {
      // ... a取不到,会报错
      // 类型“RouteComponentProps<any, StaticContext, unknown> & { children?: ReactNode; }”上不存在属性“a”。ts(2339)
    });
    

    这一堆报错我们很懵先不管他,我们直接声明 App 的参数类型:

    // 示例二
    import React from "react";
    import { withRouter } from "react-router";
    interface IProps {}
    const App = withRouter(({}: IProps) => {
      //  类型“({}: IProps) => any”的参数不能赋给类型“ComponentClass<RouteComponentProps<any,
      //  StaticContext, unknown>, any> | FunctionComponent<RouteComponentProps<any, StaticContext,
      //  unknown>> | (FunctionComponent<...> & ComponentClass<...>) | (ComponentClass<...> &
      //  FunctionComponent<...>)”的参数。
      //  不能将类型“({}: IProps) => any”分配给类型“FunctionComponent<RouteComponentProps<any, StaticContext, unknown>>”。
      //  参数“__0”和“props” 的类型不兼容。
      //  类型 "RouteComponentProps<any, StaticContext, unknown> & { children?: ReactNode; }" 中缺少属性 "a",但类型 "IProps" 中需要该属性。
    });
    

    即使什么都不写也是一堆报错,?,此时真的不知道怎么办,TS 不知道怎么办的时候就点进去看代码,发现 withRouter 是有两个泛型参数的:

    // RouteComponentProps是从react-router中声明的router参数类型,而ComponentType就是我们熟知的class组件或者函数组件,返回值我们先不管
    export function withRouter<
      P extends RouteComponentProps<any>,
      C extends React.ComponentType<P>
    >(
      component: C & React.ComponentType<P>
    ): React.ComponentClass<
      Omit<P, keyof RouteComponentProps<any>> & WithRouterProps<C>
    > &
      WithRouterStatics<C>;
    

    根据这个函数的声明是否能正确地写出 withRouter 的泛型参数呢?

    TS是最好的语言(一)

    显然是要使用 RouteComponentProps,它需要传进去我们的路由参数

    export interface RouteComponentProps<
      Params extends { [K in keyof Params]?: string } = {},
      C extends StaticContext = StaticContext,
      S = H.LocationState
    > {
      history: H.History<S>;
      location: H.Location<S>;
      match: match<Params>;
      staticContext?: C;
    }
    

    所以我们声明两个类型,一个是函数本身接受的参数,一个是路由参数

    interface IProps {
        name:string
    }
    interface IRouteProps = RouteComponentProps<{
        appId:string
    }>
    const App = withRouter<IRouteProps, FC<IRouteProps & IProps>>(({ name, match }) => {
        // appId可以获得到代码提示
        // ...
        // const { params: { appId } } = match
    }
    

    此时感受到了一点:从来没有像写 TS 这样的享受,能够把逻辑写的更加明确,代码更加潇洒,而且还有提示

    还有一类组件,它们是路由渲染的组件,本身带有RouteComponentProps,所以不需要使用withRouter包装

    const App:FC<IRouteProps & IProps>> = ({history,match,name})=>{
    
    }
    

    现在 react-router 有了 hooks,我们完全可以直接使用 hooks 来获取 history对象

    const App:FC<IProps> = () => {
      const history = useHistory();
    };
    

    下面我们着重来看 withRouter 和 RouteComponentProps 的类型声明中的小技巧

    小技巧

    1. in keyof

      Params extends { [K in keyof Params]?: string } = {}

      这两个经常成对出现,它能够把类型中的 key 提取出来,in 则类似于遍历所有 key 设置到类型中去,上面这段代码将 Params 所有的 value 设置为可选的 string 类型

    2. Omit

      Omit<P, keyof RouteComponentProps<any>> & WithRouterProps<C>

      Omit 是 TS 内置的类型,它的作用就是剔除掉某个属性与值,第二个参数是要剔除的属性值,详细的讲解可以参考这篇文章:

    原文发布于我的博客: missop.github.io/2020/12/26/…


    起源地下载网 » TS是最好的语言(一)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元