翼度科技»论坛 编程开发 JavaScript 查看内容

OpenTiny 跨端、跨框架组件库升级TypeScript,10万行代码重获新生

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
摘要:一份精心准备的《JS项目改造TS指南》文档供大家参考,顺便介绍TS<template>
<input ref="el" />
</template>基础知识和<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>在<template>
<input ref="el" />
</template>Vue<template>
<input ref="el" />
</template>中的实践。
本文分享自华为云社区《历史性的时刻!OpenTiny<template>
<input ref="el" />
</template>跨端、跨框架组件库正式升级<template>
<input ref="el" />
</template>TypeScript,10<template>
<input ref="el" />
</template>万行代码重获新生!
》,作者:Kagol。
根据<template>
<input ref="el" />
</template>The<template>
<input ref="el" />
</template>Software<template>
<input ref="el" />
</template>House<template>
<input ref="el" />
</template>发布的《2022<template>
<input ref="el" />
</template>前端开发市场状态调查报告》数据显示,使用<template>
<input ref="el" />
</template>TypeScript<template>
<input ref="el" />
</template>的人数已经达到<template>
<input ref="el" />
</template>84%,和<template>
<input ref="el" />
</template>2021<template>
<input ref="el" />
</template>年相比增加了<template>
<input ref="el" />
</template>7<template>
<input ref="el" />
</template>个百分点。
3月16日发布了<template>
<input ref="el" />
</template>TypeScript<template>
<input ref="el" />
</template>5.0<template>
<input ref="el" />
</template>版本。TypeScript<template>
<input ref="el" />
</template>可谓逐年火热,使用者呈现逐年上升的趋势,再不学起来就说不过去。
我们<template>
<input ref="el" />
</template>OpenTiny<template>
<input ref="el" />
</template>近期做了一次大的升级,将原来运行了<template>
<input ref="el" />
</template>9年<template>
<input ref="el" />
</template>的<template>
<input ref="el" />
</template>JavaScript<template>
<input ref="el" />
</template>代码升级到了<template>
<input ref="el" />
</template>TypeScript,并通过<template>
<input ref="el" />
</template>Monorepo<template>
<input ref="el" />
</template>进行子包的管理,还在用<template>
<input ref="el" />
</template>JavaScript<template>
<input ref="el" />
</template>的朋友抓紧升级哦,我特意准备了一份《JS项目改造TS指南》文档供大家参考,顺便介绍了一些<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>基础知识和<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>在<template>
<input ref="el" />
</template>Vue<template>
<input ref="el" />
</template>中的一些实践。
通过本文你将收获:

  • 通过了解<template>
    <input ref="el" />
    </template>TS<template>
    <input ref="el" />
    </template>的四大好处,说服自己下定决心学习<template>
    <input ref="el" />
    </template>TS
  • 5<template>
    <input ref="el" />
    </template>分钟学习<template>
    <input ref="el" />
    </template>TS<template>
    <input ref="el" />
    </template>最基础和常用的知识点,快速入门,包教包会
  • 了解如何在<template>
    <input ref="el" />
    </template>Vue<template>
    <input ref="el" />
    </template>中使用<template>
    <input ref="el" />
    </template>TypeScript,给<template>
    <input ref="el" />
    </template>Vue2<template>
    <input ref="el" />
    </template>开发者切换到<template>
    <input ref="el" />
    </template>Vue3<template>
    <input ref="el" />
    </template>+<template>
    <input ref="el" />
    </template>TypeScript<template>
    <input ref="el" />
    </template>提供最基本的参考
  • 如何将现有的<template>
    <input ref="el" />
    </template>JS<template>
    <input ref="el" />
    </template>项目改造成<template>
    <input ref="el" />
    </template>TS<template>
    <input ref="el" />
    </template>项目
1<template>
<input ref="el" />
</template>学习<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>的好处


1.1<template>
<input ref="el" />
</template>好处一:紧跟潮流:让自己看起来很酷


如果你没学过<template>
<input ref="el" />
</template>TS
你的前端朋友:都<template>
<input ref="el" />
</template>2023<template>
<input ref="el" />
</template>年了,你还不会<template>
<input ref="el" />
</template>TS?给你一个眼色你自己感悟吧
如果你学过<template>
<input ref="el" />
</template>TS
你的前端朋友:哇,你们的项目已经用上<template>
<input ref="el" />
</template>Vue3<template>
<input ref="el" />
</template>+<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>啦,看起来真棒!教教我吧
如果说上面那个好处太虚了,那下面的3条好处可都是实实在在能让自己受益的。
1.2<template>
<input ref="el" />
</template>好处二:智能提示:提升开发者体验和效率


当循环一个对象数组时,对象的属性列表可以直接显示出来,不用到对象的定义中去查询该对象有哪些属性。
通过调用后台接口获取的异步数据也可以通过TS类型进行智能提示,这样相当于集成了接口文档,后续后台修改字段,我们很容易就能发现。
Vue<template>
<input ref="el" />
</template>组件的属性和事件都可以智能提示。
下图是我们OpenTiny跨端跨框架前端组件库中的<template>
<input ref="el" />
</template>Alert<template>
<input ref="el" />
</template>组件,当在组件标签中输入<template>
<input ref="el" />
</template>des<template>
<input ref="el" />
</template>时,会自动提示<template>
<input ref="el" />
</template>description<template>
<input ref="el" />
</template>属性;当输入<template>
<input ref="el" />
</template>@c<template>
<input ref="el" />
</template>时,会自动提示<template>
<input ref="el" />
</template>@close<template>
<input ref="el" />
</template>事件。
1.3<template>
<input ref="el" />
</template>好处三:错误标记:代码哪里有问题一眼就知道


在<template>
<input ref="el" />
</template>JS<template>
<input ref="el" />
</template>项目使用不存在的对象属性,在编码阶段不容易看出来,到运行时才会报错。
在<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目使用不存在的对象属性,在IDE中会有红色波浪线标记,鼠标移上去能看到具体的错误信息。
在<template>
<input ref="el" />
</template>JS<template>
<input ref="el" />
</template>项目,调用方法时拼错单词不容易被发现,要在运行时才会将错误暴露出来。
在<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目会有红色波浪线提示,一眼就看出拼错单词。
1.4<template>
<input ref="el" />
</template>好处四:类型约束:用我的代码就得听我的


你写了一个工具函数<template>
<input ref="el" />
</template>getType<template>
<input ref="el" />
</template>给别人用,限定参数只能是指定的字符串,这时如果使用这个函数的人传入其他字符串,就会有红色波浪线提示。
Vue<template>
<input ref="el" />
</template>组件也是一样的,可以限定组件<template>
<input ref="el" />
</template>props<template>
<input ref="el" />
</template>的类型,组件的使用者如果传入不正确的类型,将会有错误提示,比如:我们<template>
<input ref="el" />
</template>OpenTiny<template>
<input ref="el" />
</template>的<template>
<input ref="el" />
</template>Alert<template>
<input ref="el" />
</template>组件,closable<template>
<input ref="el" />
</template>只能传入<template>
<input ref="el" />
</template>Boolean<template>
<input ref="el" />
</template>值,如果传入一个字符串就会有错误提示。
2<template>
<input ref="el" />
</template>极简<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>基础,5分钟学会


以下内容虽然不多,但包含了实际项目开发中最实用的部分,对于<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>入门者来说也是能很快学会的,学不会的找我,手把手教,包教包会,有手就会写。
2.1<template>
<input ref="el" />
</template>基本类型


用得较多的类型就下面5个,更多类型请参考:TS官网文档

  • 布尔<template>
    <input ref="el" />
    </template>boolean
  • 数值<template>
    <input ref="el" />
    </template>number
  • 字符串<template>
    <input ref="el" />
    </template>string
  • 空值<template>
    <input ref="el" />
    </template>void:表示没有任何返回值的函数
  • 任意<template>
    <input ref="el" />
    </template>any:表示不被类型检查
用法也很简单:
  1. let<template>
  2. <input ref="el" />
  3. </template>isDone:<template>
  4. <input ref="el" />
  5. </template>boolean<template>
  6. <input ref="el" />
  7. </template>=<template>
  8. <input ref="el" />
  9. </template>false;
  10. let<template>
  11. <input ref="el" />
  12. </template>myFavoriteNumber:<template>
  13. <input ref="el" />
  14. </template>number<template>
  15. <input ref="el" />
  16. </template>=<template>
  17. <input ref="el" />
  18. </template>6;
  19. let<template>
  20. <input ref="el" />
  21. </template>myName:<template>
  22. <input ref="el" />
  23. </template>string<template>
  24. <input ref="el" />
  25. </template>=<template>
  26. <input ref="el" />
  27. </template>'Kagol';
  28. function<template>
  29. <input ref="el" />
  30. </template>alertName(name:<template>
  31. <input ref="el" />
  32. </template>string):<template>
  33. <input ref="el" />
  34. </template>void<template>
  35. <input ref="el" />
  36. </template>{<template>
  37. <input ref="el" />
  38. </template>
  39. <template>
  40. <input ref="el" />
  41. </template>console.log(`My<template>
  42. <input ref="el" />
  43. </template>name<template>
  44. <input ref="el" />
  45. </template>is<template>
  46. <input ref="el" />
  47. </template>${name}`);<template>
  48. <input ref="el" />
  49. </template>
  50. }
复制代码
默认情况下,name<template>
<input ref="el" />
</template>会自动类型推导成<template>
<input ref="el" />
</template>string<template>
<input ref="el" />
</template>类型,此时如果给它赋值为一个<template>
<input ref="el" />
</template>number<template>
<input ref="el" />
</template>类型的值,会出现错误提示。
  1. let<template>
  2. <input ref="el" />
  3. </template>name<template>
  4. <input ref="el" />
  5. </template>=<template>
  6. <input ref="el" />
  7. </template>'Kagol'<template>
  8. <input ref="el" />
  9. </template>
  10. name<template>
  11. <input ref="el" />
  12. </template>=<template>
  13. <input ref="el" />
  14. </template>6
复制代码
如果给<template>
<input ref="el" />
</template>name<template>
<input ref="el" />
</template>设置<template>
<input ref="el" />
</template>any<template>
<input ref="el" />
</template>类型,表示不做类型检查,这时错误提示消失。
  1. let<template>
  2. <input ref="el" />
  3. </template>name:<template>
  4. <input ref="el" />
  5. </template>any<template>
  6. <input ref="el" />
  7. </template>=<template>
  8. <input ref="el" />
  9. </template>'Kagol'<template>
  10. <input ref="el" />
  11. </template>
  12. name<template>
  13. <input ref="el" />
  14. </template>=<template>
  15. <input ref="el" />
  16. </template>6
复制代码
2.2<template>
<input ref="el" />
</template>函数


主要定义函数参数和返回值类型。
看一下例子:
  1. const<template>
  2. <input ref="el" />
  3. </template>sum<template>
  4. <input ref="el" />
  5. </template>=<template>
  6. <input ref="el" />
  7. </template>(x:<template>
  8. <input ref="el" />
  9. </template>number,<template>
  10. <input ref="el" />
  11. </template>y:<template>
  12. <input ref="el" />
  13. </template>number):<template>
  14. <input ref="el" />
  15. </template>number<template>
  16. <input ref="el" />
  17. </template>=><template>
  18. <input ref="el" />
  19. </template>{<template>
  20. <input ref="el" />
  21. </template>
  22. <template>
  23. <input ref="el" />
  24. </template>return<template>
  25. <input ref="el" />
  26. </template>x<template>
  27. <input ref="el" />
  28. </template>+<template>
  29. <input ref="el" />
  30. </template>y<template>
  31. <input ref="el" />
  32. </template><template>
  33. <input ref="el" />
  34. </template>
  35. }
复制代码
以上代码包含以下<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>校验规则:

  • 调用<template>
    <input ref="el" />
    </template>sum<template>
    <input ref="el" />
    </template>函数时,必须传入两个参数,多一个或者少一个都不行
  • 并且这两个参数的类型要为<template>
    <input ref="el" />
    </template>number<template>
    <input ref="el" />
    </template>类型
  • 且函数的返回值为<template>
    <input ref="el" />
    </template>number<template>
    <input ref="el" />
    </template>类型
少参数:
多参数:
参数类型错误:
返回值:
用问号<template>
<input ref="el" />
</template>?<template>
<input ref="el" />
</template>可以表示该参数是可选的。
  1. const<template>
  2. <input ref="el" />
  3. </template>sum<template>
  4. <input ref="el" />
  5. </template>=<template>
  6. <input ref="el" />
  7. </template>(x:<template>
  8. <input ref="el" />
  9. </template>number,<template>
  10. <input ref="el" />
  11. </template>y?:<template>
  12. <input ref="el" />
  13. </template>number):<template>
  14. <input ref="el" />
  15. </template>number<template>
  16. <input ref="el" />
  17. </template>=><template>
  18. <input ref="el" />
  19. </template>{<template>
  20. <input ref="el" />
  21. </template>
  22. <template>
  23. <input ref="el" />
  24. </template>return<template>
  25. <input ref="el" />
  26. </template>x<template>
  27. <input ref="el" />
  28. </template>+<template>
  29. <input ref="el" />
  30. </template>(y<template>
  31. <input ref="el" />
  32. </template>||<template>
  33. <input ref="el" />
  34. </template>0);<template>
  35. <input ref="el" />
  36. </template>
  37. }<template>
  38. <input ref="el" />
  39. </template>
  40. sum(1)<template>
  41. <input ref="el" />
  42. </template>
复制代码
如果将<template>
<input ref="el" />
</template>y<template>
<input ref="el" />
</template>定义为可选参数,则调用<template>
<input ref="el" />
</template>sum<template>
<input ref="el" />
</template>函数时可以只传入一个参数。
需要注意的是,可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必需参数了。
给<template>
<input ref="el" />
</template>y<template>
<input ref="el" />
</template>增加默认值<template>
<input ref="el" />
</template>0<template>
<input ref="el" />
</template>之后,y<template>
<input ref="el" />
</template>会自动类型推导成<template>
<input ref="el" />
</template>number<template>
<input ref="el" />
</template>类型,不需要加<template>
<input ref="el" />
</template>number<template>
<input ref="el" />
</template>类型,并且由于有默认值,也不需要加可选参数。
  1. const<template>
  2. <input ref="el" />
  3. </template>sum<template>
  4. <input ref="el" />
  5. </template>=<template>
  6. <input ref="el" />
  7. </template>(x:<template>
  8. <input ref="el" />
  9. </template>number,<template>
  10. <input ref="el" />
  11. </template>y<template>
  12. <input ref="el" />
  13. </template>=<template>
  14. <input ref="el" />
  15. </template>0):<template>
  16. <input ref="el" />
  17. </template>number<template>
  18. <input ref="el" />
  19. </template>=><template>
  20. <input ref="el" />
  21. </template>{<template>
  22. <input ref="el" />
  23. </template>
  24. <template>
  25. <input ref="el" />
  26. </template>return<template>
  27. <input ref="el" />
  28. </template>x<template>
  29. <input ref="el" />
  30. </template>+<template>
  31. <input ref="el" />
  32. </template>y<template>
  33. <input ref="el" />
  34. </template><template>
  35. <input ref="el" />
  36. </template>
  37. }
  38. sum(1)<template>
  39. <input ref="el" />
  40. </template>
  41. sum(1,<template>
  42. <input ref="el" />
  43. </template>2)<template>
  44. <input ref="el" />
  45. </template>
复制代码
2.3<template>
<input ref="el" />
</template>数组


数组类型有两种表示方式:

  • 类型<template>
    <input ref="el" />
    </template>+<template>
    <input ref="el" />
    </template>方括号<template>
    <input ref="el" />
    </template>表示法
  • 泛型<template>
    <input ref="el" />
    </template>表示法
  1. //<template>
  2. <input ref="el" />
  3. </template>`类型<template>
  4. <input ref="el" />
  5. </template>+<template>
  6. <input ref="el" />
  7. </template>方括号`<template>
  8. <input ref="el" />
  9. </template>表示法
  10. let<template>
  11. <input ref="el" />
  12. </template>fibonacci:<template>
  13. <input ref="el" />
  14. </template>number[]<template>
  15. <input ref="el" />
  16. </template>=<template>
  17. <input ref="el" />
  18. </template>[1,<template>
  19. <input ref="el" />
  20. </template>1,<template>
  21. <input ref="el" />
  22. </template>2,<template>
  23. <input ref="el" />
  24. </template>3,<template>
  25. <input ref="el" />
  26. </template>5]
  27. //<template>
  28. <input ref="el" />
  29. </template>泛型表示法
  30. let<template>
  31. <input ref="el" />
  32. </template>fibonacci:<template>
  33. <input ref="el" />
  34. </template>Array<number><template>
  35. <input ref="el" />
  36. </template>=<template>
  37. <input ref="el" />
  38. </template>[1,<template>
  39. <input ref="el" />
  40. </template>1,<template>
  41. <input ref="el" />
  42. </template>2,<template>
  43. <input ref="el" />
  44. </template>3,<template>
  45. <input ref="el" />
  46. </template>5]
复制代码
这两种都可以表示数组类型,看自己喜好进行选择即可。
如果是类数组,则不可以用数组的方式定义类型,因为它不是真的数组,需要用<template>
<input ref="el" />
</template>interface<template>
<input ref="el" />
</template>进行定义
  1. interface<template>
  2. <input ref="el" />
  3. </template>IArguments<template>
  4. <input ref="el" />
  5. </template>{
  6. <template>
  7. <input ref="el" />
  8. </template>[index:<template>
  9. <input ref="el" />
  10. </template>number]:<template>
  11. <input ref="el" />
  12. </template>any;
  13. <template>
  14. <input ref="el" />
  15. </template><template>
  16. <input ref="el" />
  17. </template>length:<template>
  18. <input ref="el" />
  19. </template>number;
  20. <template>
  21. <input ref="el" />
  22. </template>callee:<template>
  23. <input ref="el" />
  24. </template>Function;
  25. }
  26. function<template>
  27. <input ref="el" />
  28. </template>sum()<template>
  29. <input ref="el" />
  30. </template>{
  31. <template>
  32. <input ref="el" />
  33. </template>let<template>
  34. <input ref="el" />
  35. </template>args:<template>
  36. <input ref="el" />
  37. </template>IArguments<template>
  38. <input ref="el" />
  39. </template>=<template>
  40. <input ref="el" />
  41. </template>arguments
  42. }
复制代码
IArguments<template>
<input ref="el" />
</template>类型已在<template>
<input ref="el" />
</template>TypeScript<template>
<input ref="el" />
</template>中内置,类似的还有很多:
  1. let<template>
  2. <input ref="el" />
  3. </template>body:<template>
  4. <input ref="el" />
  5. </template>HTMLElement<template>
  6. <input ref="el" />
  7. </template>=<template>
  8. <input ref="el" />
  9. </template>document.body;
  10. let<template>
  11. <input ref="el" />
  12. </template>allDiv:<template>
  13. <input ref="el" />
  14. </template>NodeList<template>
  15. <input ref="el" />
  16. </template>=<template>
  17. <input ref="el" />
  18. </template>document.querySelectorAll('div');
  19. document.addEventListener('click',<template>
  20. <input ref="el" />
  21. </template>function(e:<template>
  22. <input ref="el" />
  23. </template>MouseEvent)<template>
  24. <input ref="el" />
  25. </template>{
  26. <template>
  27. <input ref="el" />
  28. </template>//<template>
  29. <input ref="el" />
  30. </template>Do<template>
  31. <input ref="el" />
  32. </template>something
  33. });
复制代码
如果数组里的元素类型并不都是相同的怎么办呢?
这时<template>
<input ref="el" />
</template>any<template>
<input ref="el" />
</template>类型就发挥作用啦啦
  1. let<template>
  2. <input ref="el" />
  3. </template>list:<template>
  4. <input ref="el" />
  5. </template>any[]<template>
  6. <input ref="el" />
  7. </template>=<template>
  8. <input ref="el" />
  9. </template>['OpenTiny',<template>
  10. <input ref="el" />
  11. </template>112,<template>
  12. <input ref="el" />
  13. </template>{<template>
  14. <input ref="el" />
  15. </template>website:<template>
  16. <input ref="el" />
  17. </template>'https://opentiny.design/'<template>
  18. <input ref="el" />
  19. </template>}];
复制代码
2.4<template>
<input ref="el" />
</template>接口


接口简单理解就是一个对象的“轮廓”
  1. interface<template>
  2. <input ref="el" />
  3. </template>IResourceItem<template>
  4. <input ref="el" />
  5. </template>{
  6. <template>
  7. <input ref="el" />
  8. </template><template>
  9. <input ref="el" />
  10. </template>name:<template>
  11. <input ref="el" />
  12. </template>string;
  13. <template>
  14. <input ref="el" />
  15. </template>value?:<template>
  16. <input ref="el" />
  17. </template>string<template>
  18. <input ref="el" />
  19. </template>|<template>
  20. <input ref="el" />
  21. </template>number;
  22. <template>
  23. <input ref="el" />
  24. </template>total?:<template>
  25. <input ref="el" />
  26. </template>number;
  27. <template>
  28. <input ref="el" />
  29. </template>checked?:<template>
  30. <input ref="el" />
  31. </template>boolean;
  32. }
复制代码
接口是可以继承接口的
  1. interface<template>
  2. <input ref="el" />
  3. </template>IClosableResourceItem<template>
  4. <input ref="el" />
  5. </template>extends<template>
  6. <input ref="el" />
  7. </template>IResourceItem<template>
  8. <input ref="el" />
  9. </template>{
  10. <template>
  11. <input ref="el" />
  12. </template>closable?:<template>
  13. <input ref="el" />
  14. </template>boolean;
  15. }
复制代码
这样<template>
<input ref="el" />
</template>IClosableResourceItem<template>
<input ref="el" />
</template>就包含了<template>
<input ref="el" />
</template>IResourceItem<template>
<input ref="el" />
</template>属性和自己的<template>
<input ref="el" />
</template>closable<template>
<input ref="el" />
</template>可选属性。
接口也是可以被类实现的
  1. interface<template>
  2. <input ref="el" />
  3. </template>Alarm<template>
  4. <input ref="el" />
  5. </template>{
  6. <template>
  7. <input ref="el" />
  8. </template>alert():<template>
  9. <input ref="el" />
  10. </template>void;
  11. }
  12. class<template>
  13. <input ref="el" />
  14. </template>Door<template>
  15. <input ref="el" />
  16. </template>{
  17. }
  18. class<template>
  19. <input ref="el" />
  20. </template>SecurityDoor<template>
  21. <input ref="el" />
  22. </template>extends<template>
  23. <input ref="el" />
  24. </template>Door<template>
  25. <input ref="el" />
  26. </template>implements<template>
  27. <input ref="el" />
  28. </template>Alarm<template>
  29. <input ref="el" />
  30. </template>{
  31. <template>
  32. <input ref="el" />
  33. </template>alert()<template>
  34. <input ref="el" />
  35. </template>{
  36. <template>
  37. <input ref="el" />
  38. </template>console.log('SecurityDoor<template>
  39. <input ref="el" />
  40. </template>alert')
  41. <template>
  42. <input ref="el" />
  43. </template>}
  44. }
复制代码
如果类实现了一个接口,却不写具体的实现代码,则会有错误提示
2.5<template>
<input ref="el" />
</template>联合类型<template>
<input ref="el" />
</template>&<template>
<input ref="el" />
</template>类型别名


联合类型是指取值可以为多种类型中的一种,而类型别名常用于联合类型。
看以下例子:
  1. //<template>
  2. <input ref="el" />
  3. </template>联合类型
  4. let<template>
  5. <input ref="el" />
  6. </template>myFavoriteNumber:<template>
  7. <input ref="el" />
  8. </template>string<template>
  9. <input ref="el" />
  10. </template>|<template>
  11. <input ref="el" />
  12. </template>number
  13. myFavoriteNumber<template>
  14. <input ref="el" />
  15. </template>=<template>
  16. <input ref="el" />
  17. </template>'six'
  18. myFavoriteNumber<template>
  19. <input ref="el" />
  20. </template>=<template>
  21. <input ref="el" />
  22. </template>6
  23. //<template>
  24. <input ref="el" />
  25. </template>类型别名
  26. type<template>
  27. <input ref="el" />
  28. </template>FavoriteNumber<template>
  29. <input ref="el" />
  30. </template>=<template>
  31. <input ref="el" />
  32. </template>string<template>
  33. <input ref="el" />
  34. </template>|<template>
  35. <input ref="el" />
  36. </template>number
  37. let<template>
  38. <input ref="el" />
  39. </template>myFavoriteNumber:<template>
  40. <input ref="el" />
  41. </template>FavoriteNumber
复制代码
当<template>
<input ref="el" />
</template>TypeScript<template>
<input ref="el" />
</template>不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
  1. function<template>
  2. <input ref="el" />
  3. </template>getLength(something:<template>
  4. <input ref="el" />
  5. </template>string<template>
  6. <input ref="el" />
  7. </template>|<template>
  8. <input ref="el" />
  9. </template>number):<template>
  10. <input ref="el" />
  11. </template>number<template>
  12. <input ref="el" />
  13. </template>{
  14. <template>
  15. <input ref="el" />
  16. </template>return<template>
  17. <input ref="el" />
  18. </template>something.length
  19. }
  20. //<template>
  21. <input ref="el" />
  22. </template>index.ts(2,22):<template>
  23. <input ref="el" />
  24. </template>error<template>
  25. <input ref="el" />
  26. </template>TS2339:<template>
  27. <input ref="el" />
  28. </template>Property<template>
  29. <input ref="el" />
  30. </template>'length'<template>
  31. <input ref="el" />
  32. </template>does<template>
  33. <input ref="el" />
  34. </template>not<template>
  35. <input ref="el" />
  36. </template>exist<template>
  37. <input ref="el" />
  38. </template>on<template>
  39. <input ref="el" />
  40. </template>type<template>
  41. <input ref="el" />
  42. </template>'string<template>
  43. <input ref="el" />
  44. </template>|<template>
  45. <input ref="el" />
  46. </template>number'.
  47. //<template>
  48. <input ref="el" />
  49. </template><template>
  50. <input ref="el" />
  51. </template><template>
  52. <input ref="el" />
  53. </template>Property<template>
  54. <input ref="el" />
  55. </template>'length'<template>
  56. <input ref="el" />
  57. </template>does<template>
  58. <input ref="el" />
  59. </template>not<template>
  60. <input ref="el" />
  61. </template>exist<template>
  62. <input ref="el" />
  63. </template>on<template>
  64. <input ref="el" />
  65. </template>type<template>
  66. <input ref="el" />
  67. </template>'number'.
  68. 上例中,length<template>
  69. <input ref="el" />
  70. </template>不是<template>
  71. <input ref="el" />
  72. </template>string<template>
  73. <input ref="el" />
  74. </template>和<template>
  75. <input ref="el" />
  76. </template>number<template>
  77. <input ref="el" />
  78. </template>的共有属性,所以会报错。
  79. 访问<template>
  80. <input ref="el" />
  81. </template>string<template>
  82. <input ref="el" />
  83. </template>和<template>
  84. <input ref="el" />
  85. </template>number<template>
  86. <input ref="el" />
  87. </template>的共有属性是没问题的:
  88. function<template>
  89. <input ref="el" />
  90. </template>getString(something:<template>
  91. <input ref="el" />
  92. </template>string<template>
  93. <input ref="el" />
  94. </template>|<template>
  95. <input ref="el" />
  96. </template>number):<template>
  97. <input ref="el" />
  98. </template>string<template>
  99. <input ref="el" />
  100. </template>{
  101. <template>
  102. <input ref="el" />
  103. </template>return<template>
  104. <input ref="el" />
  105. </template>something.toString()
  106. }
复制代码
2.6<template>
<input ref="el" />
</template>类型断言


类型断言(Type<template>
<input ref="el" />
</template>Assertion)可以用来手动指定一个值的类型。
语法:值<template>
<input ref="el" />
</template>as<template>
<input ref="el" />
</template>类型,比如:(animal<template>
<input ref="el" />
</template>as<template>
<input ref="el" />
</template>Fish).swim()
类型断言主要有以下用途:

  • 将一个联合类型断言为其中一个类型
  • 将一个父类断言为更加具体的子类
  • 将任何一个类型断言为<template>
    <input ref="el" />
    </template>any
  • 将<template>
    <input ref="el" />
    </template>any<template>
    <input ref="el" />
    </template>断言为一个具体的类型
我们一个个来看。
用途1:将一个联合类型断言为其中一个类型
  1. interface<template>
  2. <input ref="el" />
  3. </template>Cat<template>
  4. <input ref="el" />
  5. </template>{
  6. <template>
  7. <input ref="el" />
  8. </template><template>
  9. <input ref="el" />
  10. </template>name:<template>
  11. <input ref="el" />
  12. </template>string;
  13. <template>
  14. <input ref="el" />
  15. </template>run():<template>
  16. <input ref="el" />
  17. </template>void;
  18. }
  19. interface<template>
  20. <input ref="el" />
  21. </template>Fish<template>
  22. <input ref="el" />
  23. </template>{
  24. <template>
  25. <input ref="el" />
  26. </template><template>
  27. <input ref="el" />
  28. </template>name:<template>
  29. <input ref="el" />
  30. </template>string;
  31. <template>
  32. <input ref="el" />
  33. </template>swim():<template>
  34. <input ref="el" />
  35. </template>void;
  36. }
  37. const<template>
  38. <input ref="el" />
  39. </template>animal:<template>
  40. <input ref="el" />
  41. </template>Cat<template>
  42. <input ref="el" />
  43. </template>|<template>
  44. <input ref="el" />
  45. </template>Fish<template>
  46. <input ref="el" />
  47. </template>=<template>
  48. <input ref="el" />
  49. </template>new<template>
  50. <input ref="el" />
  51. </template>Animal()
  52. animal.swim()
复制代码
animal<template>
<input ref="el" />
</template>是一个联合类型,可能是猫<template>
<input ref="el" />
</template>Cat,也可能是鱼<template>
<input ref="el" />
</template>Fish,如果直接调用<template>
<input ref="el" />
</template>swim<template>
<input ref="el" />
</template>方法是要出现错误提示的,因为猫不会游泳。
这时类型断言就派上用场啦啦,因为调用的是<template>
<input ref="el" />
</template>swim<template>
<input ref="el" />
</template>方法,那肯定是鱼,所以直接断言为<template>
<input ref="el" />
</template>Fish<template>
<input ref="el" />
</template>就不会出现错误提示。
  1. const<template>
  2. <input ref="el" />
  3. </template>animal:<template>
  4. <input ref="el" />
  5. </template>Cat<template>
  6. <input ref="el" />
  7. </template>|<template>
  8. <input ref="el" />
  9. </template>Fish<template>
  10. <input ref="el" />
  11. </template>=<template>
  12. <input ref="el" />
  13. </template>new<template>
  14. <input ref="el" />
  15. </template>Animal()
  16. (animal<template>
  17. <input ref="el" />
  18. </template>as<template>
  19. <input ref="el" />
  20. </template>Fish).swim()
复制代码
用途2:将一个父类断言为更加具体的子类
  1. class<template>
  2. <input ref="el" />
  3. </template>ApiError<template>
  4. <input ref="el" />
  5. </template>extends<template>
  6. <input ref="el" />
  7. </template>Error<template>
  8. <input ref="el" />
  9. </template>{
  10. <template>
  11. <input ref="el" />
  12. </template><template>
  13. <input ref="el" />
  14. </template>code:<template>
  15. <input ref="el" />
  16. </template>number<template>
  17. <input ref="el" />
  18. </template>=<template>
  19. <input ref="el" />
  20. </template>0;
  21. }
  22. class<template>
  23. <input ref="el" />
  24. </template>HttpError<template>
  25. <input ref="el" />
  26. </template>extends<template>
  27. <input ref="el" />
  28. </template>Error<template>
  29. <input ref="el" />
  30. </template>{
  31. <template>
  32. <input ref="el" />
  33. </template>statusCode:<template>
  34. <input ref="el" />
  35. </template>number<template>
  36. <input ref="el" />
  37. </template>=<template>
  38. <input ref="el" />
  39. </template>200;
  40. }
  41. function<template>
  42. <input ref="el" />
  43. </template>isApiError(error:<template>
  44. <input ref="el" />
  45. </template>Error)<template>
  46. <input ref="el" />
  47. </template>{
  48. <template>
  49. <input ref="el" />
  50. </template>if<template>
  51. <input ref="el" />
  52. </template>(typeof<template>
  53. <input ref="el" />
  54. </template>(error<template>
  55. <input ref="el" />
  56. </template>as<template>
  57. <input ref="el" />
  58. </template>ApiError).code<template>
  59. <input ref="el" />
  60. </template>===<template>
  61. <input ref="el" />
  62. </template>'number')<template>
  63. <input ref="el" />
  64. </template>{
  65. <template>
  66. <input ref="el" />
  67. </template>return<template>
  68. <input ref="el" />
  69. </template>true;
  70. <template>
  71. <input ref="el" />
  72. </template>}
  73. <template>
  74. <input ref="el" />
  75. </template>return<template>
  76. <input ref="el" />
  77. </template>false;
  78. }
复制代码
ApiError<template>
<input ref="el" />
</template>和<template>
<input ref="el" />
</template>HttpError<template>
<input ref="el" />
</template>都继承自<template>
<input ref="el" />
</template>Error<template>
<input ref="el" />
</template>父类,error<template>
<input ref="el" />
</template>变量的类型是<template>
<input ref="el" />
</template>Error,去取<template>
<input ref="el" />
</template>code<template>
<input ref="el" />
</template>变量肯定是不行,因为取的是<template>
<input ref="el" />
</template>code<template>
<input ref="el" />
</template>变量,我们可以直接断言为<template>
<input ref="el" />
</template>ApiError<template>
<input ref="el" />
</template>类型。
用途3:将任何一个类型断言为<template>
<input ref="el" />
</template>any
这个非常有用,看一下例子:
  1. function<template>
  2. <input ref="el" />
  3. </template>getCacheData(key:<template>
  4. <input ref="el" />
  5. </template>string):<template>
  6. <input ref="el" />
  7. </template>any<template>
  8. <input ref="el" />
  9. </template>{
  10. <template>
  11. <input ref="el" />
  12. </template>return<template>
  13. <input ref="el" />
  14. </template>(window<template>
  15. <input ref="el" />
  16. </template>as<template>
  17. <input ref="el" />
  18. </template>any).cache[key];
  19. }
  20. interface<template>
  21. <input ref="el" />
  22. </template>Cat<template>
  23. <input ref="el" />
  24. </template>{
  25. <template>
  26. <input ref="el" />
  27. </template><template>
  28. <input ref="el" />
  29. </template>name:<template>
  30. <input ref="el" />
  31. </template>string;
  32. <template>
  33. <input ref="el" />
  34. </template>run():<template>
  35. <input ref="el" />
  36. </template>void;
  37. }
  38. const<template>
  39. <input ref="el" />
  40. </template>tom<template>
  41. <input ref="el" />
  42. </template>=<template>
  43. <input ref="el" />
  44. </template>getCacheData('tom')<template>
  45. <input ref="el" />
  46. </template>as<template>
  47. <input ref="el" />
  48. </template>Cat;
复制代码
getCacheData<template>
<input ref="el" />
</template>是一个历史遗留函数,不是你写的,由于他返回<template>
<input ref="el" />
</template>any<template>
<input ref="el" />
</template>类型,就等于放弃了<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>的类型检验,假如<template>
<input ref="el" />
</template>tom<template>
<input ref="el" />
</template>是一只猫,里面有<template>
<input ref="el" />
</template>name<template>
<input ref="el" />
</template>属性和<template>
<input ref="el" />
</template>run()<template>
<input ref="el" />
</template>方法,但由于返回<template>
<input ref="el" />
</template>any<template>
<input ref="el" />
</template>类型,tom.<template>
<input ref="el" />
</template>是没有任何提示的。
如果将其断言为<template>
<input ref="el" />
</template>Cat<template>
<input ref="el" />
</template>类型,就可以<template>
<input ref="el" />
</template>点<template>
<input ref="el" />
</template>出<template>
<input ref="el" />
</template>name<template>
<input ref="el" />
</template>属性和<template>
<input ref="el" />
</template>run()<template>
<input ref="el" />
</template>方法。
用途4:将<template>
<input ref="el" />
</template>any<template>
<input ref="el" />
</template>断言为一个具体的类型
这个比较常见的场景是给<template>
<input ref="el" />
</template>window<template>
<input ref="el" />
</template>挂在一个自己的变量和方法。
  1. window.foo<template>
  2. <input ref="el" />
  3. </template>=<template>
  4. <input ref="el" />
  5. </template>1;
  6. //<template>
  7. <input ref="el" />
  8. </template>index.ts:1:8<template>
  9. <input ref="el" />
  10. </template>-<template>
  11. <input ref="el" />
  12. </template>error<template>
  13. <input ref="el" />
  14. </template>TS2339:<template>
  15. <input ref="el" />
  16. </template>Property<template>
  17. <input ref="el" />
  18. </template>'foo'<template>
  19. <input ref="el" />
  20. </template>does<template>
  21. <input ref="el" />
  22. </template>not<template>
  23. <input ref="el" />
  24. </template>exist<template>
  25. <input ref="el" />
  26. </template>on<template>
  27. <input ref="el" />
  28. </template>type<template>
  29. <input ref="el" />
  30. </template>'Window<template>
  31. <input ref="el" />
  32. </template>&<template>
  33. <input ref="el" />
  34. </template>typeof<template>
  35. <input ref="el" />
  36. </template>globalThis'.
  37. (window<template>
  38. <input ref="el" />
  39. </template>as<template>
  40. <input ref="el" />
  41. </template>any).foo<template>
  42. <input ref="el" />
  43. </template>=<template>
  44. <input ref="el" />
  45. </template>1;
复制代码
由于<template>
<input ref="el" />
</template>window<template>
<input ref="el" />
</template>下没有<template>
<input ref="el" />
</template>foo<template>
<input ref="el" />
</template>变量,直接赋值会有错误提示,将<template>
<input ref="el" />
</template>window<template>
<input ref="el" />
</template>断言为<template>
<input ref="el" />
</template>any<template>
<input ref="el" />
</template>就没问题啦啦。
2.7<template>
<input ref="el" />
</template>元组


数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。
  1. let<template>
  2. <input ref="el" />
  3. </template>tom:<template>
  4. <input ref="el" />
  5. </template>[string,<template>
  6. <input ref="el" />
  7. </template>number]<template>
  8. <input ref="el" />
  9. </template>=<template>
  10. <input ref="el" />
  11. </template>['Tom',<template>
  12. <input ref="el" />
  13. </template>25];
复制代码
给元组类型赋值时,数组每一项的类型需要和元组定义的类型对应上。
当赋值或访问一个已知索引的元素时,会得到正确的类型:
  1. let<template>
  2. <input ref="el" />
  3. </template>tom:<template>
  4. <input ref="el" />
  5. </template>[string,<template>
  6. <input ref="el" />
  7. </template>number];
  8. tom[0]<template>
  9. <input ref="el" />
  10. </template>=<template>
  11. <input ref="el" />
  12. </template>'Tom';
  13. tom[1]<template>
  14. <input ref="el" />
  15. </template>=<template>
  16. <input ref="el" />
  17. </template>25;
  18. tom[0].slice(1);
  19. tom[1].toFixed(2);
复制代码
也可以只赋值其中一项:
  1. let<template>
  2. <input ref="el" />
  3. </template>tom:<template>
  4. <input ref="el" />
  5. </template>[string,<template>
  6. <input ref="el" />
  7. </template>number];
  8. tom[0]<template>
  9. <input ref="el" />
  10. </template>=<template>
  11. <input ref="el" />
  12. </template>'Tom';
复制代码
但是当直接对元组类型的变量进行初始化或者赋值的时候,需要提供所有元组类型中指定的项。
  1. let<template>
  2. <input ref="el" />
  3. </template>tom:<template>
  4. <input ref="el" />
  5. </template>[string,<template>
  6. <input ref="el" />
  7. </template>number];
  8. tom<template>
  9. <input ref="el" />
  10. </template>=<template>
  11. <input ref="el" />
  12. </template>['Tom'];
  13. //<template>
  14. <input ref="el" />
  15. </template>Property<template>
  16. <input ref="el" />
  17. </template>'1'<template>
  18. <input ref="el" />
  19. </template>is<template>
  20. <input ref="el" />
  21. </template>missing<template>
  22. <input ref="el" />
  23. </template>in<template>
  24. <input ref="el" />
  25. </template>type<template>
  26. <input ref="el" />
  27. </template>'[string]'<template>
  28. <input ref="el" />
  29. </template>but<template>
  30. <input ref="el" />
  31. </template>required<template>
  32. <input ref="el" />
  33. </template>in<template>
  34. <input ref="el" />
  35. </template>type<template>
  36. <input ref="el" />
  37. </template>'[string,<template>
  38. <input ref="el" />
  39. </template>number]'.
复制代码
当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型:
  1. let<template>
  2. <input ref="el" />
  3. </template>tom:<template>
  4. <input ref="el" />
  5. </template>[string,<template>
  6. <input ref="el" />
  7. </template>number];
  8. tom<template>
  9. <input ref="el" />
  10. </template>=<template>
  11. <input ref="el" />
  12. </template>['Tom',<template>
  13. <input ref="el" />
  14. </template>25];
  15. tom.push('male');
  16. tom.push(true);
  17. //<template>
  18. <input ref="el" />
  19. </template>Argument<template>
  20. <input ref="el" />
  21. </template>of<template>
  22. <input ref="el" />
  23. </template>type<template>
  24. <input ref="el" />
  25. </template>'true'<template>
  26. <input ref="el" />
  27. </template>is<template>
  28. <input ref="el" />
  29. </template>not<template>
  30. <input ref="el" />
  31. </template>assignable<template>
  32. <input ref="el" />
  33. </template>to<template>
  34. <input ref="el" />
  35. </template>parameter<template>
  36. <input ref="el" />
  37. </template>of<template>
  38. <input ref="el" />
  39. </template>type<template>
  40. <input ref="el" />
  41. </template>'string<template>
  42. <input ref="el" />
  43. </template>|<template>
  44. <input ref="el" />
  45. </template>number'.
复制代码
push<template>
<input ref="el" />
</template>字符串和数字都可以,布尔就不行。
2.8<template>
<input ref="el" />
</template>枚举


枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。
  1. enum<template>
  2. <input ref="el" />
  3. </template>Days<template>
  4. <input ref="el" />
  5. </template>{Sun,<template>
  6. <input ref="el" />
  7. </template>Mon,<template>
  8. <input ref="el" />
  9. </template>Tue,<template>
  10. <input ref="el" />
  11. </template>Wed,<template>
  12. <input ref="el" />
  13. </template>Thu,<template>
  14. <input ref="el" />
  15. </template>Fri,<template>
  16. <input ref="el" />
  17. </template>Sat}
复制代码
枚举成员会被赋值为从<template>
<input ref="el" />
</template>0<template>
<input ref="el" />
</template>开始递增的数字,同时也会对枚举值到枚举名进行反向映射:
  1. console.log(Days.Sun<template>
  2. <input ref="el" />
  3. </template>===<template>
  4. <input ref="el" />
  5. </template>0)<template>
  6. <input ref="el" />
  7. </template>//<template>
  8. <input ref="el" />
  9. </template>true
  10. console.log(Days[0]<template>
  11. <input ref="el" />
  12. </template>===<template>
  13. <input ref="el" />
  14. </template>'Sun')<template>
  15. <input ref="el" />
  16. </template>//<template>
  17. <input ref="el" />
  18. </template>true
  19. console.log('Days',<template>
  20. <input ref="el" />
  21. </template>Days)
复制代码
手动赋值:未手动赋值的枚举项会接着上一个枚举项递增。
  1. enum<template>
  2. <input ref="el" />
  3. </template>Days<template>
  4. <input ref="el" />
  5. </template>{Sun<template>
  6. <input ref="el" />
  7. </template>=<template>
  8. <input ref="el" />
  9. </template>7,<template>
  10. <input ref="el" />
  11. </template>Mon<template>
  12. <input ref="el" />
  13. </template>=<template>
  14. <input ref="el" />
  15. </template>1,<template>
  16. <input ref="el" />
  17. </template>Tue,<template>
  18. <input ref="el" />
  19. </template>Wed,<template>
  20. <input ref="el" />
  21. </template>Thu,<template>
  22. <input ref="el" />
  23. </template>Fri,<template>
  24. <input ref="el" />
  25. </template>Sat}
复制代码
2.9<template>
<input ref="el" />
</template>类


给类加上<template>
<input ref="el" />
</template>TypeScript<template>
<input ref="el" />
</template>的类型很简单,与接口类似:
  1. class<template>
  2. <input ref="el" />
  3. </template>Animal<template>
  4. <input ref="el" />
  5. </template>{
  6. <template>
  7. <input ref="el" />
  8. </template><template>
  9. <input ref="el" />
  10. </template>name:<template>
  11. <input ref="el" />
  12. </template>string
  13. <template>
  14. <input ref="el" />
  15. </template>constructor(name:<template>
  16. <input ref="el" />
  17. </template>string)<template>
  18. <input ref="el" />
  19. </template>{
  20. <template>
  21. <input ref="el" />
  22. </template>this.name<template>
  23. <input ref="el" />
  24. </template>=<template>
  25. <input ref="el" />
  26. </template>name
  27. <template>
  28. <input ref="el" />
  29. </template>}
  30. <template>
  31. <input ref="el" />
  32. </template>sayHi(welcome:<template>
  33. <input ref="el" />
  34. </template>string):<template>
  35. <input ref="el" />
  36. </template>string<template>
  37. <input ref="el" />
  38. </template>{
  39. <template>
  40. <input ref="el" />
  41. </template>return<template>
  42. <input ref="el" />
  43. </template>`${welcome}<template>
  44. <input ref="el" />
  45. </template>My<template>
  46. <input ref="el" />
  47. </template>name<template>
  48. <input ref="el" />
  49. </template>is<template>
  50. <input ref="el" />
  51. </template>${this.name}`
  52. <template>
  53. <input ref="el" />
  54. </template>}
  55. }
复制代码
类的语法涉及到较多概念,请参考:
2.10<template>
<input ref="el" />
</template>泛型


泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
可以简单理解为定义函数时的形参。
设想以下场景,我们有一个<template>
<input ref="el" />
</template>print<template>
<input ref="el" />
</template>函数,输入什么,原样打印,函数的入参和返回值类型是一致的。
一开始只需要打印字符串:
  1. function<template>
  2. <input ref="el" />
  3. </template>print(arg:<template>
  4. <input ref="el" />
  5. </template>string):<template>
  6. <input ref="el" />
  7. </template>string<template>
  8. <input ref="el" />
  9. </template>{
  10. <template>
  11. <input ref="el" />
  12. </template>return<template>
  13. <input ref="el" />
  14. </template>arg
  15. }
复制代码
后面需求变了,除了能打印字符串,还要能打印数字:
  1. function<template>
  2. <input ref="el" />
  3. </template>print(arg:<template>
  4. <input ref="el" />
  5. </template>string<template>
  6. <input ref="el" />
  7. </template>|<template>
  8. <input ref="el" />
  9. </template>number):<template>
  10. <input ref="el" />
  11. </template>string<template>
  12. <input ref="el" />
  13. </template>|<template>
  14. <input ref="el" />
  15. </template>number<template>
  16. <input ref="el" />
  17. </template>{
  18. <template>
  19. <input ref="el" />
  20. </template>return<template>
  21. <input ref="el" />
  22. </template>arg
  23. }
复制代码
假如需求又变了,要打印布尔值、对象、数组,甚至自定义的类型,怎么办,写一串联合类型?显然是不可取的,用<template>
<input ref="el" />
</template>any?那就失去了<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>类型校验能力,沦为<template>
<input ref="el" />
</template>JS。
  1. function<template>
  2. <input ref="el" />
  3. </template>print(arg:<template>
  4. <input ref="el" />
  5. </template>any):<template>
  6. <input ref="el" />
  7. </template>any<template>
  8. <input ref="el" />
  9. </template>{
  10. <template>
  11. <input ref="el" />
  12. </template><template>
  13. <input ref="el" />
  14. </template>return<template>
  15. <input ref="el" />
  16. </template>arg
  17. }
复制代码
解决这个问题的完美方法就是泛型!
print<template>
<input ref="el" />
</template>后面加上一对尖括号,里面写一个<template>
<input ref="el" />
</template>T,这个<template>
<input ref="el" />
</template>T<template>
<input ref="el" />
</template>就类似是一个类型的形参。
这个类型形参可以在函数入参里用,也可以在函数返回值使用,甚至也可以在函数体里面的变量、函数里面用。
  1. function<template>
  2. <input ref="el" />
  3. </template>print<T>(arg:<template>
  4. <input ref="el" />
  5. </template>T):<template>
  6. <input ref="el" />
  7. </template>T<template>
  8. <input ref="el" />
  9. </template>{
  10. <template>
  11. <input ref="el" />
  12. </template>return<template>
  13. <input ref="el" />
  14. </template>arg
  15. }
复制代码
那么实参哪里来?用的时候传进来!
  1. const<template>
  2. <input ref="el" />
  3. </template>res<template>
  4. <input ref="el" />
  5. </template>=<template>
  6. <input ref="el" />
  7. </template>print<number>(123)
复制代码
我们还可以使用泛型来约束后端接口参数类型。
  1. import<template>
  2. <input ref="el" />
  3. </template>axios<template>
  4. <input ref="el" />
  5. </template>from<template>
  6. <input ref="el" />
  7. </template>'axios'
  8. interface<template>
  9. <input ref="el" />
  10. </template>API<template>
  11. <input ref="el" />
  12. </template>{
  13. <template>
  14. <input ref="el" />
  15. </template>'/book/detail':<template>
  16. <input ref="el" />
  17. </template>{
  18. <template>
  19. <input ref="el" />
  20. </template><template>
  21. <input ref="el" />
  22. </template><template>
  23. <input ref="el" />
  24. </template><template>
  25. <input ref="el" />
  26. </template><template>
  27. <input ref="el" />
  28. </template><template>
  29. <input ref="el" />
  30. </template>id:<template>
  31. <input ref="el" />
  32. </template>number,
  33. <template>
  34. <input ref="el" />
  35. </template>},
  36. <template>
  37. <input ref="el" />
  38. </template>'/book/comment':<template>
  39. <input ref="el" />
  40. </template>{
  41. <template>
  42. <input ref="el" />
  43. </template><template>
  44. <input ref="el" />
  45. </template><template>
  46. <input ref="el" />
  47. </template><template>
  48. <input ref="el" />
  49. </template><template>
  50. <input ref="el" />
  51. </template><template>
  52. <input ref="el" />
  53. </template>id:<template>
  54. <input ref="el" />
  55. </template>number
  56. <template>
  57. <input ref="el" />
  58. </template><template>
  59. <input ref="el" />
  60. </template><template>
  61. <input ref="el" />
  62. </template><template>
  63. <input ref="el" />
  64. </template><template>
  65. <input ref="el" />
  66. </template><template>
  67. <input ref="el" />
  68. </template>comment:<template>
  69. <input ref="el" />
  70. </template>string
  71. <template>
  72. <input ref="el" />
  73. </template>}
  74. <template>
  75. <input ref="el" />
  76. </template>...
  77. }
  78. function<template>
  79. <input ref="el" />
  80. </template>request<T<template>
  81. <input ref="el" />
  82. </template>extends<template>
  83. <input ref="el" />
  84. </template>keyof<template>
  85. <input ref="el" />
  86. </template>API>(url:<template>
  87. <input ref="el" />
  88. </template>T,<template>
  89. <input ref="el" />
  90. </template>obj:<template>
  91. <input ref="el" />
  92. </template>API[T])<template>
  93. <input ref="el" />
  94. </template>{
  95. <template>
  96. <input ref="el" />
  97. </template>return<template>
  98. <input ref="el" />
  99. </template>axios.post(url,<template>
  100. <input ref="el" />
  101. </template>obj)
  102. }
  103. request('/book/comment',<template>
  104. <input ref="el" />
  105. </template>{
  106. <template>
  107. <input ref="el" />
  108. </template><template>
  109. <input ref="el" />
  110. </template>id:<template>
  111. <input ref="el" />
  112. </template>1,
  113. <template>
  114. <input ref="el" />
  115. </template><template>
  116. <input ref="el" />
  117. </template>comment:<template>
  118. <input ref="el" />
  119. </template>'非常棒!'
  120. })
复制代码
以上代码对接口进行了约束:

  • url<template>
    <input ref="el" />
    </template>只能是<template>
    <input ref="el" />
    </template>API<template>
    <input ref="el" />
    </template>中定义过的,其他<template>
    <input ref="el" />
    </template>url<template>
    <input ref="el" />
    </template>都会提示错误


  • 接口参数<template>
    <input ref="el" />
    </template>obj<template>
    <input ref="el" />
    </template>必须和<template>
    <input ref="el" />
    </template>url<template>
    <input ref="el" />
    </template>能对应上,不能少属性,属性类型也不能错
而且调用<template>
<input ref="el" />
</template>request<template>
<input ref="el" />
</template>方法时,也会提示<template>
<input ref="el" />
</template>url<template>
<input ref="el" />
</template>可以选择哪些
如果后台改了接口参数名,我们一眼就看出来了,都不用去找接口文档,是不是很厉害!
泛型的例子参考了前端阿林的文章:

  • 轻松拿下<template>
    <input ref="el" />
    </template>TS<template>
    <input ref="el" />
    </template>泛型
3<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>在<template>
<input ref="el" />
</template>Vue<template>
<input ref="el" />
</template>中的实践


3.1<template>
<input ref="el" />
</template>定义组件<template>
<input ref="el" />
</template>props<template>
<input ref="el" />
</template>的类型


不使用<template>
<input ref="el" />
</template>setup<template>
<input ref="el" />
</template>语法糖
  1. export<template>
  2. <input ref="el" />
  3. </template>default<template>
  4. <input ref="el" />
  5. </template>defineComponent({
  6. <template>
  7. <input ref="el" />
  8. </template><template>
  9. <input ref="el" />
  10. </template>props:<template>
  11. <input ref="el" />
  12. </template>{
  13. <template>
  14. <input ref="el" />
  15. </template><template>
  16. <input ref="el" />
  17. </template><template>
  18. <input ref="el" />
  19. </template><template>
  20. <input ref="el" />
  21. </template>items:<template>
  22. <input ref="el" />
  23. </template>{
  24. <template>
  25. <input ref="el" />
  26. </template><template>
  27. <input ref="el" />
  28. </template><template>
  29. <input ref="el" />
  30. </template><template>
  31. <input ref="el" />
  32. </template><template>
  33. <input ref="el" />
  34. </template><template>
  35. <input ref="el" />
  36. </template>type:<template>
  37. <input ref="el" />
  38. </template>Object<template>
  39. <input ref="el" />
  40. </template>as<template>
  41. <input ref="el" />
  42. </template>PropType<IResourceItem[]>,
  43. <template>
  44. <input ref="el" />
  45. </template>default()<template>
  46. <input ref="el" />
  47. </template>{
  48. <template>
  49. <input ref="el" />
  50. </template>return<template>
  51. <input ref="el" />
  52. </template>[]
  53. <template>
  54. <input ref="el" />
  55. </template>}
  56. <template>
  57. <input ref="el" />
  58. </template>},
  59. <template>
  60. <input ref="el" />
  61. </template><template>
  62. <input ref="el" />
  63. </template><template>
  64. <input ref="el" />
  65. </template><template>
  66. <input ref="el" />
  67. </template>span:<template>
  68. <input ref="el" />
  69. </template>{
  70. <template>
  71. <input ref="el" />
  72. </template><template>
  73. <input ref="el" />
  74. </template><template>
  75. <input ref="el" />
  76. </template><template>
  77. <input ref="el" />
  78. </template><template>
  79. <input ref="el" />
  80. </template><template>
  81. <input ref="el" />
  82. </template>type:<template>
  83. <input ref="el" />
  84. </template>Number,
  85. <template>
  86. <input ref="el" />
  87. </template>default:<template>
  88. <input ref="el" />
  89. </template>4
  90. <template>
  91. <input ref="el" />
  92. </template>},
  93. <template>
  94. <input ref="el" />
  95. </template><template>
  96. <input ref="el" />
  97. </template><template>
  98. <input ref="el" />
  99. </template><template>
  100. <input ref="el" />
  101. </template>gap:<template>
  102. <input ref="el" />
  103. </template>{
  104. <template>
  105. <input ref="el" />
  106. </template><template>
  107. <input ref="el" />
  108. </template><template>
  109. <input ref="el" />
  110. </template><template>
  111. <input ref="el" />
  112. </template><template>
  113. <input ref="el" />
  114. </template><template>
  115. <input ref="el" />
  116. </template>type:<template>
  117. <input ref="el" />
  118. </template>[String,<template>
  119. <input ref="el" />
  120. </template>Number]<template>
  121. <input ref="el" />
  122. </template>as<template>
  123. <input ref="el" />
  124. </template>PropType<string<template>
  125. <input ref="el" />
  126. </template>|<template>
  127. <input ref="el" />
  128. </template>number>,
  129. <template>
  130. <input ref="el" />
  131. </template>default:<template>
  132. <input ref="el" />
  133. </template>'12px'
  134. <template>
  135. <input ref="el" />
  136. </template>},
  137. <template>
  138. <input ref="el" />
  139. </template><template>
  140. <input ref="el" />
  141. </template><template>
  142. <input ref="el" />
  143. </template><template>
  144. <input ref="el" />
  145. </template>block:<template>
  146. <input ref="el" />
  147. </template>{
  148. <template>
  149. <input ref="el" />
  150. </template><template>
  151. <input ref="el" />
  152. </template><template>
  153. <input ref="el" />
  154. </template><template>
  155. <input ref="el" />
  156. </template><template>
  157. <input ref="el" />
  158. </template><template>
  159. <input ref="el" />
  160. </template>type:<template>
  161. <input ref="el" />
  162. </template>Object<template>
  163. <input ref="el" />
  164. </template>as<template>
  165. <input ref="el" />
  166. </template>PropType<Component>,
  167. <template>
  168. <input ref="el" />
  169. </template>default:<template>
  170. <input ref="el" />
  171. </template>TvpBlock
  172. <template>
  173. <input ref="el" />
  174. </template>},
  175. <template>
  176. <input ref="el" />
  177. </template>beforeClose:<template>
  178. <input ref="el" />
  179. </template>Function<template>
  180. <input ref="el" />
  181. </template>as<template>
  182. <input ref="el" />
  183. </template>PropType<()<template>
  184. <input ref="el" />
  185. </template>=><template>
  186. <input ref="el" />
  187. </template>boolean>
  188. <template>
  189. <input ref="el" />
  190. </template>}
  191. })
复制代码
使用<template>
<input ref="el" />
</template>setup<template>
<input ref="el" />
</template>语法糖<template>
<input ref="el" />
</template>–<template>
<input ref="el" />
</template>runtime<template>
<input ref="el" />
</template>声明
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>PropType,<template>
  6. <input ref="el" />
  7. </template>Component<template>
  8. <input ref="el" />
  9. </template>}<template>
  10. <input ref="el" />
  11. </template>from<template>
  12. <input ref="el" />
  13. </template>'vue'
  14. const<template>
  15. <input ref="el" />
  16. </template>props<template>
  17. <input ref="el" />
  18. </template>=<template>
  19. <input ref="el" />
  20. </template>defineProps({
  21. <template>
  22. <input ref="el" />
  23. </template><template>
  24. <input ref="el" />
  25. </template>items:<template>
  26. <input ref="el" />
  27. </template>{
  28. <template>
  29. <input ref="el" />
  30. </template><template>
  31. <input ref="el" />
  32. </template><template>
  33. <input ref="el" />
  34. </template><template>
  35. <input ref="el" />
  36. </template>type:<template>
  37. <input ref="el" />
  38. </template>Object<template>
  39. <input ref="el" />
  40. </template>as<template>
  41. <input ref="el" />
  42. </template>PropType<IResourceItem[]>,
  43. <template>
  44. <input ref="el" />
  45. </template>default()<template>
  46. <input ref="el" />
  47. </template>{
  48. <template>
  49. <input ref="el" />
  50. </template>return<template>
  51. <input ref="el" />
  52. </template>[]
  53. <template>
  54. <input ref="el" />
  55. </template>}
  56. <template>
  57. <input ref="el" />
  58. </template>},
  59. <template>
  60. <input ref="el" />
  61. </template><template>
  62. <input ref="el" />
  63. </template>span:<template>
  64. <input ref="el" />
  65. </template>{
  66. <template>
  67. <input ref="el" />
  68. </template><template>
  69. <input ref="el" />
  70. </template><template>
  71. <input ref="el" />
  72. </template><template>
  73. <input ref="el" />
  74. </template>type:<template>
  75. <input ref="el" />
  76. </template>Number,
  77. <template>
  78. <input ref="el" />
  79. </template>default:<template>
  80. <input ref="el" />
  81. </template>4
  82. <template>
  83. <input ref="el" />
  84. </template>},
  85. <template>
  86. <input ref="el" />
  87. </template><template>
  88. <input ref="el" />
  89. </template>gap:<template>
  90. <input ref="el" />
  91. </template>{
  92. <template>
  93. <input ref="el" />
  94. </template><template>
  95. <input ref="el" />
  96. </template><template>
  97. <input ref="el" />
  98. </template><template>
  99. <input ref="el" />
  100. </template>type:<template>
  101. <input ref="el" />
  102. </template>[String,<template>
  103. <input ref="el" />
  104. </template>Number]<template>
  105. <input ref="el" />
  106. </template>as<template>
  107. <input ref="el" />
  108. </template>PropType<string<template>
  109. <input ref="el" />
  110. </template>|<template>
  111. <input ref="el" />
  112. </template>number>,
  113. <template>
  114. <input ref="el" />
  115. </template>default:<template>
  116. <input ref="el" />
  117. </template>'12px'
  118. <template>
  119. <input ref="el" />
  120. </template>},
  121. <template>
  122. <input ref="el" />
  123. </template><template>
  124. <input ref="el" />
  125. </template>block:<template>
  126. <input ref="el" />
  127. </template>{
  128. <template>
  129. <input ref="el" />
  130. </template><template>
  131. <input ref="el" />
  132. </template><template>
  133. <input ref="el" />
  134. </template><template>
  135. <input ref="el" />
  136. </template>type:<template>
  137. <input ref="el" />
  138. </template>Object<template>
  139. <input ref="el" />
  140. </template>as<template>
  141. <input ref="el" />
  142. </template>PropType<Component>,
  143. <template>
  144. <input ref="el" />
  145. </template>default:<template>
  146. <input ref="el" />
  147. </template>TvpBlock
  148. <template>
  149. <input ref="el" />
  150. </template>},
  151. <template>
  152. <input ref="el" />
  153. </template>beforeClose:<template>
  154. <input ref="el" />
  155. </template>Function<template>
  156. <input ref="el" />
  157. </template>as<template>
  158. <input ref="el" />
  159. </template>PropType<()<template>
  160. <input ref="el" />
  161. </template>=><template>
  162. <input ref="el" />
  163. </template>boolean>
  164. })
复制代码
使用<template>
<input ref="el" />
</template>setup<template>
<input ref="el" />
</template>语法糖<template>
<input ref="el" />
</template>–<template>
<input ref="el" />
</template>type-based<template>
<input ref="el" />
</template>声明
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>Component,<template>
  6. <input ref="el" />
  7. </template>withDefaults<template>
  8. <input ref="el" />
  9. </template>}<template>
  10. <input ref="el" />
  11. </template>from<template>
  12. <input ref="el" />
  13. </template>'vue'
  14. interface<template>
  15. <input ref="el" />
  16. </template>Props<template>
  17. <input ref="el" />
  18. </template>{
  19. <template>
  20. <input ref="el" />
  21. </template><template>
  22. <input ref="el" />
  23. </template>items:<template>
  24. <input ref="el" />
  25. </template>IResourceItem[]
  26. <template>
  27. <input ref="el" />
  28. </template><template>
  29. <input ref="el" />
  30. </template>span:<template>
  31. <input ref="el" />
  32. </template>number
  33. <template>
  34. <input ref="el" />
  35. </template><template>
  36. <input ref="el" />
  37. </template>gap:<template>
  38. <input ref="el" />
  39. </template>string<template>
  40. <input ref="el" />
  41. </template>|<template>
  42. <input ref="el" />
  43. </template>number
  44. <template>
  45. <input ref="el" />
  46. </template><template>
  47. <input ref="el" />
  48. </template>block:<template>
  49. <input ref="el" />
  50. </template>Component
  51. <template>
  52. <input ref="el" />
  53. </template>beforeClose:<template>
  54. <input ref="el" />
  55. </template>()<template>
  56. <input ref="el" />
  57. </template>=><template>
  58. <input ref="el" />
  59. </template>void
  60. }
  61. const<template>
  62. <input ref="el" />
  63. </template>props<template>
  64. <input ref="el" />
  65. </template>=<template>
  66. <input ref="el" />
  67. </template>withDefaults(defineProps<Props>(),<template>
  68. <input ref="el" />
  69. </template>{
  70. <template>
  71. <input ref="el" />
  72. </template>items:<template>
  73. <input ref="el" />
  74. </template>()<template>
  75. <input ref="el" />
  76. </template>=><template>
  77. <input ref="el" />
  78. </template>[],
  79. <template>
  80. <input ref="el" />
  81. </template><template>
  82. <input ref="el" />
  83. </template>span:<template>
  84. <input ref="el" />
  85. </template>4,
  86. <template>
  87. <input ref="el" />
  88. </template><template>
  89. <input ref="el" />
  90. </template>gap:<template>
  91. <input ref="el" />
  92. </template>'12px',
  93. <template>
  94. <input ref="el" />
  95. </template><template>
  96. <input ref="el" />
  97. </template>block:<template>
  98. <input ref="el" />
  99. </template>TvpBlock
  100. })
  101. IResourceItem:
  102. interface<template>
  103. <input ref="el" />
  104. </template>IResourceItem<template>
  105. <input ref="el" />
  106. </template>{
  107. <template>
  108. <input ref="el" />
  109. </template><template>
  110. <input ref="el" />
  111. </template>name:<template>
  112. <input ref="el" />
  113. </template>string;
  114. <template>
  115. <input ref="el" />
  116. </template>value?:<template>
  117. <input ref="el" />
  118. </template>string<template>
  119. <input ref="el" />
  120. </template>|<template>
  121. <input ref="el" />
  122. </template>number;
  123. <template>
  124. <input ref="el" />
  125. </template>total?:<template>
  126. <input ref="el" />
  127. </template>number;
  128. <template>
  129. <input ref="el" />
  130. </template>checked?:<template>
  131. <input ref="el" />
  132. </template>boolean;
  133. <template>
  134. <input ref="el" />
  135. </template>closable?:<template>
  136. <input ref="el" />
  137. </template>boolean;
  138. }
复制代码
3.2<template>
<input ref="el" />
</template>定义<template>
<input ref="el" />
</template>emits<template>
<input ref="el" />
</template>类型


不使用<template>
<input ref="el" />
</template>setup<template>
<input ref="el" />
</template>语法糖
  1. export<template>
  2. <input ref="el" />
  3. </template>default<template>
  4. <input ref="el" />
  5. </template>defineComponent({
  6. <template>
  7. <input ref="el" />
  8. </template><template>
  9. <input ref="el" />
  10. </template>emits:<template>
  11. <input ref="el" />
  12. </template>['change',<template>
  13. <input ref="el" />
  14. </template>'update'],
  15. <template>
  16. <input ref="el" />
  17. </template>setup(props,<template>
  18. <input ref="el" />
  19. </template>{<template>
  20. <input ref="el" />
  21. </template>emit<template>
  22. <input ref="el" />
  23. </template>})<template>
  24. <input ref="el" />
  25. </template>{
  26. <template>
  27. <input ref="el" />
  28. </template>emit('change')
  29. <template>
  30. <input ref="el" />
  31. </template>}
  32. })
复制代码
使用<template>
<input ref="el" />
</template>setup<template>
<input ref="el" />
</template>语法糖
  1. [/code][size=4]3.3<template>
  2. <input ref="el" />
  3. </template>定义<template>
  4. <input ref="el" />
  5. </template>ref<template>
  6. <input ref="el" />
  7. </template>类型[/size]
  8. 默认会自动进行类型推导
  9. [code]import<template>
  10. <input ref="el" />
  11. </template>{<template>
  12. <input ref="el" />
  13. </template>ref<template>
  14. <input ref="el" />
  15. </template>}<template>
  16. <input ref="el" />
  17. </template>from<template>
  18. <input ref="el" />
  19. </template>'vue'
  20. //<template>
  21. <input ref="el" />
  22. </template>inferred<template>
  23. <input ref="el" />
  24. </template>type:<template>
  25. <input ref="el" />
  26. </template>Ref<number>
  27. const<template>
  28. <input ref="el" />
  29. </template>year<template>
  30. <input ref="el" />
  31. </template>=<template>
  32. <input ref="el" />
  33. </template>ref(2020)
  34. //<template>
  35. <input ref="el" />
  36. </template>=><template>
  37. <input ref="el" />
  38. </template>TS<template>
  39. <input ref="el" />
  40. </template>Error:<template>
  41. <input ref="el" />
  42. </template>Type<template>
  43. <input ref="el" />
  44. </template>'string'<template>
  45. <input ref="el" />
  46. </template>is<template>
  47. <input ref="el" />
  48. </template>not<template>
  49. <input ref="el" />
  50. </template>assignable<template>
  51. <input ref="el" />
  52. </template>to<template>
  53. <input ref="el" />
  54. </template>type<template>
  55. <input ref="el" />
  56. </template>'number'.
  57. year.value<template>
  58. <input ref="el" />
  59. </template>=<template>
  60. <input ref="el" />
  61. </template>'2020'
复制代码
两种声明<template>
<input ref="el" />
</template>ref<template>
<input ref="el" />
</template>类型的方法
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>ref<template>
  6. <input ref="el" />
  7. </template>}<template>
  8. <input ref="el" />
  9. </template>from<template>
  10. <input ref="el" />
  11. </template>'vue'
  12. import<template>
  13. <input ref="el" />
  14. </template>type<template>
  15. <input ref="el" />
  16. </template>{<template>
  17. <input ref="el" />
  18. </template>Ref<template>
  19. <input ref="el" />
  20. </template>}<template>
  21. <input ref="el" />
  22. </template>from<template>
  23. <input ref="el" />
  24. </template>'vue'
  25. //<template>
  26. <input ref="el" />
  27. </template>方式一
  28. const<template>
  29. <input ref="el" />
  30. </template>year:<template>
  31. <input ref="el" />
  32. </template>Ref<string<template>
  33. <input ref="el" />
  34. </template>|<template>
  35. <input ref="el" />
  36. </template>number><template>
  37. <input ref="el" />
  38. </template>=<template>
  39. <input ref="el" />
  40. </template>ref('2020')
  41. year.value<template>
  42. <input ref="el" />
  43. </template>=<template>
  44. <input ref="el" />
  45. </template>2020<template>
  46. <input ref="el" />
  47. </template>//<template>
  48. <input ref="el" />
  49. </template>ok!
  50. //<template>
  51. <input ref="el" />
  52. </template>方式二
  53. //<template>
  54. <input ref="el" />
  55. </template>resulting<template>
  56. <input ref="el" />
  57. </template>type:<template>
  58. <input ref="el" />
  59. </template>Ref<string<template>
  60. <input ref="el" />
  61. </template>|<template>
  62. <input ref="el" />
  63. </template>number>
  64. const<template>
  65. <input ref="el" />
  66. </template>year<template>
  67. <input ref="el" />
  68. </template>=<template>
  69. <input ref="el" />
  70. </template>ref<string<template>
  71. <input ref="el" />
  72. </template>|<template>
  73. <input ref="el" />
  74. </template>number>('2020')
  75. year.value<template>
  76. <input ref="el" />
  77. </template>=<template>
  78. <input ref="el" />
  79. </template>2020<template>
  80. <input ref="el" />
  81. </template>//<template>
  82. <input ref="el" />
  83. </template>ok!
复制代码
3.4<template>
<input ref="el" />
</template>定义<template>
<input ref="el" />
</template>reactive<template>
<input ref="el" />
</template>类型


默认会自动进行类型推导
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>reactive<template>
  6. <input ref="el" />
  7. </template>}<template>
  8. <input ref="el" />
  9. </template>from<template>
  10. <input ref="el" />
  11. </template>'vue'
  12. //<template>
  13. <input ref="el" />
  14. </template>inferred<template>
  15. <input ref="el" />
  16. </template>type:<template>
  17. <input ref="el" />
  18. </template>{<template>
  19. <input ref="el" />
  20. </template>title:<template>
  21. <input ref="el" />
  22. </template>string<template>
  23. <input ref="el" />
  24. </template>}
  25. const<template>
  26. <input ref="el" />
  27. </template>book<template>
  28. <input ref="el" />
  29. </template>=<template>
  30. <input ref="el" />
  31. </template>reactive({<template>
  32. <input ref="el" />
  33. </template>title:<template>
  34. <input ref="el" />
  35. </template>'Vue<template>
  36. <input ref="el" />
  37. </template>3<template>
  38. <input ref="el" />
  39. </template>Guide'<template>
  40. <input ref="el" />
  41. </template>})
复制代码
使用接口定义明确的类型
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>reactive<template>
  6. <input ref="el" />
  7. </template>}<template>
  8. <input ref="el" />
  9. </template>from<template>
  10. <input ref="el" />
  11. </template>'vue'
  12. interface<template>
  13. <input ref="el" />
  14. </template>Book<template>
  15. <input ref="el" />
  16. </template>{
  17. <template>
  18. <input ref="el" />
  19. </template><template>
  20. <input ref="el" />
  21. </template>title:<template>
  22. <input ref="el" />
  23. </template>string
  24. <template>
  25. <input ref="el" />
  26. </template>year?:<template>
  27. <input ref="el" />
  28. </template>number
  29. }
  30. const<template>
  31. <input ref="el" />
  32. </template>book:<template>
  33. <input ref="el" />
  34. </template>Book<template>
  35. <input ref="el" />
  36. </template>=<template>
  37. <input ref="el" />
  38. </template>reactive({<template>
  39. <input ref="el" />
  40. </template>title:<template>
  41. <input ref="el" />
  42. </template>'Vue<template>
  43. <input ref="el" />
  44. </template>3<template>
  45. <input ref="el" />
  46. </template>Guide'<template>
  47. <input ref="el" />
  48. </template>})
复制代码
3.5<template>
<input ref="el" />
</template>定义<template>
<input ref="el" />
</template>computed<template>
<input ref="el" />
</template>类型


默认会自动进行类型推导
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>ref,<template>
  6. <input ref="el" />
  7. </template>computed<template>
  8. <input ref="el" />
  9. </template>}<template>
  10. <input ref="el" />
  11. </template>from<template>
  12. <input ref="el" />
  13. </template>'vue'
  14. const<template>
  15. <input ref="el" />
  16. </template>count<template>
  17. <input ref="el" />
  18. </template>=<template>
  19. <input ref="el" />
  20. </template>ref(0)
  21. //<template>
  22. <input ref="el" />
  23. </template>inferred<template>
  24. <input ref="el" />
  25. </template>type:<template>
  26. <input ref="el" />
  27. </template>ComputedRef<number>
  28. const<template>
  29. <input ref="el" />
  30. </template>double<template>
  31. <input ref="el" />
  32. </template>=<template>
  33. <input ref="el" />
  34. </template>computed(()<template>
  35. <input ref="el" />
  36. </template>=><template>
  37. <input ref="el" />
  38. </template>count.value<template>
  39. <input ref="el" />
  40. </template>*<template>
  41. <input ref="el" />
  42. </template>2)
  43. //<template>
  44. <input ref="el" />
  45. </template>=><template>
  46. <input ref="el" />
  47. </template>TS<template>
  48. <input ref="el" />
  49. </template>Error:<template>
  50. <input ref="el" />
  51. </template>Property<template>
  52. <input ref="el" />
  53. </template>'split'<template>
  54. <input ref="el" />
  55. </template>does<template>
  56. <input ref="el" />
  57. </template>not<template>
  58. <input ref="el" />
  59. </template>exist<template>
  60. <input ref="el" />
  61. </template>on<template>
  62. <input ref="el" />
  63. </template>type<template>
  64. <input ref="el" />
  65. </template>'number'
  66. const<template>
  67. <input ref="el" />
  68. </template>result<template>
  69. <input ref="el" />
  70. </template>=<template>
  71. <input ref="el" />
  72. </template>double.value.split('')
复制代码
两种声明<template>
<input ref="el" />
</template>computed<template>
<input ref="el" />
</template>类型的方法
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>ComputedRef,<template>
  6. <input ref="el" />
  7. </template>computed<template>
  8. <input ref="el" />
  9. </template>}<template>
  10. <input ref="el" />
  11. </template>from<template>
  12. <input ref="el" />
  13. </template>'vue'
  14. const<template>
  15. <input ref="el" />
  16. </template>double:<template>
  17. <input ref="el" />
  18. </template>ComputedRef<number><template>
  19. <input ref="el" />
  20. </template>=<template>
  21. <input ref="el" />
  22. </template>computed(()<template>
  23. <input ref="el" />
  24. </template>=><template>
  25. <input ref="el" />
  26. </template>{
  27. <template>
  28. <input ref="el" />
  29. </template>//<template>
  30. <input ref="el" />
  31. </template>type<template>
  32. <input ref="el" />
  33. </template>error<template>
  34. <input ref="el" />
  35. </template>if<template>
  36. <input ref="el" />
  37. </template>this<template>
  38. <input ref="el" />
  39. </template>doesn't<template>
  40. <input ref="el" />
  41. </template>return<template>
  42. <input ref="el" />
  43. </template>a<template>
  44. <input ref="el" />
  45. </template>number
  46. })
  47. const<template>
  48. <input ref="el" />
  49. </template>double<template>
  50. <input ref="el" />
  51. </template>=<template>
  52. <input ref="el" />
  53. </template>computed<number>(()<template>
  54. <input ref="el" />
  55. </template>=><template>
  56. <input ref="el" />
  57. </template>{
  58. <template>
  59. <input ref="el" />
  60. </template>//<template>
  61. <input ref="el" />
  62. </template>type<template>
  63. <input ref="el" />
  64. </template>error<template>
  65. <input ref="el" />
  66. </template>if<template>
  67. <input ref="el" />
  68. </template>this<template>
  69. <input ref="el" />
  70. </template>doesn't<template>
  71. <input ref="el" />
  72. </template>return<template>
  73. <input ref="el" />
  74. </template>a<template>
  75. <input ref="el" />
  76. </template>number
  77. })
复制代码
3.6<template>
<input ref="el" />
</template>定义<template>
<input ref="el" />
</template>provide/inject<template>
<input ref="el" />
</template>类型


provide
  1. import<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>provide,<template>
  6. <input ref="el" />
  7. </template>inject<template>
  8. <input ref="el" />
  9. </template>}<template>
  10. <input ref="el" />
  11. </template>from<template>
  12. <input ref="el" />
  13. </template>'vue'
  14. import<template>
  15. <input ref="el" />
  16. </template>type<template>
  17. <input ref="el" />
  18. </template>{<template>
  19. <input ref="el" />
  20. </template>InjectionKey<template>
  21. <input ref="el" />
  22. </template>}<template>
  23. <input ref="el" />
  24. </template>from<template>
  25. <input ref="el" />
  26. </template>'vue'
  27. //<template>
  28. <input ref="el" />
  29. </template>声明<template>
  30. <input ref="el" />
  31. </template>provide<template>
  32. <input ref="el" />
  33. </template>的值为<template>
  34. <input ref="el" />
  35. </template>string<template>
  36. <input ref="el" />
  37. </template>类型
  38. const<template>
  39. <input ref="el" />
  40. </template>key<template>
  41. <input ref="el" />
  42. </template>=<template>
  43. <input ref="el" />
  44. </template>Symbol()<template>
  45. <input ref="el" />
  46. </template>as<template>
  47. <input ref="el" />
  48. </template>InjectionKey<string>
  49. provide(key,<template>
  50. <input ref="el" />
  51. </template>'foo')<template>
  52. <input ref="el" />
  53. </template>//<template>
  54. <input ref="el" />
  55. </template>providing<template>
  56. <input ref="el" />
  57. </template>non-string<template>
  58. <input ref="el" />
  59. </template>value<template>
  60. <input ref="el" />
  61. </template>will<template>
  62. <input ref="el" />
  63. </template>result<template>
  64. <input ref="el" />
  65. </template>in<template>
  66. <input ref="el" />
  67. </template>error
复制代码
inject
  1. //<template>
  2. <input ref="el" />
  3. </template>自动推导为<template>
  4. <input ref="el" />
  5. </template>string<template>
  6. <input ref="el" />
  7. </template>类型
  8. const<template>
  9. <input ref="el" />
  10. </template>foo<template>
  11. <input ref="el" />
  12. </template>=<template>
  13. <input ref="el" />
  14. </template>inject(key)<template>
  15. <input ref="el" />
  16. </template>//<template>
  17. <input ref="el" />
  18. </template>type<template>
  19. <input ref="el" />
  20. </template>of<template>
  21. <input ref="el" />
  22. </template>foo:<template>
  23. <input ref="el" />
  24. </template>string<template>
  25. <input ref="el" />
  26. </template>|<template>
  27. <input ref="el" />
  28. </template>undefined
  29. //<template>
  30. <input ref="el" />
  31. </template>明确指定为<template>
  32. <input ref="el" />
  33. </template>string<template>
  34. <input ref="el" />
  35. </template>类型
  36. const<template>
  37. <input ref="el" />
  38. </template>foo<template>
  39. <input ref="el" />
  40. </template>=<template>
  41. <input ref="el" />
  42. </template>inject<string>('foo')<template>
  43. <input ref="el" />
  44. </template>//<template>
  45. <input ref="el" />
  46. </template>type:<template>
  47. <input ref="el" />
  48. </template>string<template>
  49. <input ref="el" />
  50. </template>|<template>
  51. <input ref="el" />
  52. </template>undefined
  53. //<template>
  54. <input ref="el" />
  55. </template>增加默认值
  56. const<template>
  57. <input ref="el" />
  58. </template>foo<template>
  59. <input ref="el" />
  60. </template>=<template>
  61. <input ref="el" />
  62. </template>inject<string>('foo',<template>
  63. <input ref="el" />
  64. </template>'bar')<template>
  65. <input ref="el" />
  66. </template>//<template>
  67. <input ref="el" />
  68. </template>type:<template>
  69. <input ref="el" />
  70. </template>string
  71. //<template>
  72. <input ref="el" />
  73. </template>类型断言为<template>
  74. <input ref="el" />
  75. </template>string
  76. const<template>
  77. <input ref="el" />
  78. </template>foo<template>
  79. <input ref="el" />
  80. </template>=<template>
  81. <input ref="el" />
  82. </template>inject('foo')<template>
  83. <input ref="el" />
  84. </template>as<template>
  85. <input ref="el" />
  86. </template>string
复制代码
3.7<template>
<input ref="el" />
</template>定义模板引用的类型

  1. <template>
  2. <input ref="el" />
  3. </template>
复制代码
3.8<template>
<input ref="el" />
</template>定义组件模板引用的类型


定义一个<template>
<input ref="el" />
</template>MyModal<template>
<input ref="el" />
</template>组件
  1. [/code]在<template>
  2. <input ref="el" />
  3. </template>App.vue<template>
  4. <input ref="el" />
  5. </template>中引用<template>
  6. <input ref="el" />
  7. </template>MyModal<template>
  8. <input ref="el" />
  9. </template>组件
  10. [code]
复制代码
参考<template>
<input ref="el" />
</template>Vue<template>
<input ref="el" />
</template>官网文档:

  • TypeScript<template>
    <input ref="el" />
    </template>with<template>
    <input ref="el" />
    </template>Composition<template>
    <input ref="el" />
    </template>API
4<template>
<input ref="el" />
</template>JS<template>
<input ref="el" />
</template>项目转<template>
<input ref="el" />
</template>TS


还是使用<template>
<input ref="el" />
</template>JS<template>
<input ref="el" />
</template>的同学有福啦!为了让大家快速用上<template>
<input ref="el" />
</template>TS,享受<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>的丝滑体验,我整理了一份《JS<template>
<input ref="el" />
</template>项目改造成<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目指南》。有了这份步骤指南,JS<template>
<input ref="el" />
</template>项目转<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>不再是难事!
我们新开源的<template>
<input ref="el" />
</template>TinyVue<template>
<input ref="el" />
</template>组件库,就使用这份《JS<template>
<input ref="el" />
</template>项目改造成<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目指南》,成功地由<template>
<input ref="el" />
</template>JS<template>
<input ref="el" />
</template>项目改造成了<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目,悄悄地告诉大家:

  • TinyVue 是一套跨端、跨框架的企业级<template>
    <input ref="el" />
    </template>UI<template>
    <input ref="el" />
    </template>组件库,支持<template>
    <input ref="el" />
    </template>Vue<template>
    <input ref="el" />
    </template>2<template>
    <input ref="el" />
    </template>和<template>
    <input ref="el" />
    </template>Vue<template>
    <input ref="el" />
    </template>3,支持<template>
    <input ref="el" />
    </template>PC<template>
    <input ref="el" />
    </template>端和移动端。
  • 在内部经过9年持续打磨,服务于华为内外部上千个项目。
  • 目前代码量超过10万行。
这么庞大的代码量都能从<template>
<input ref="el" />
</template>JS<template>
<input ref="el" />
</template>转<template>
<input ref="el" />
</template>TS,其他小规模的项目更是不在话下。
为了验证自己的猜想,我又在<template>
<input ref="el" />
</template>GitHub<template>
<input ref="el" />
</template>找到了一个6年前的<template>
<input ref="el" />
</template>Vue2<template>
<input ref="el" />
</template>+<template>
<input ref="el" />
</template>JS<template>
<input ref="el" />
</template>项目,目前早已不再维护,打算尝试将其改造成<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目,结果按照这份指南,1个小时不用就搞定啦啦
https://github.com/liangxiaojuan/vue-todos
这个项目的效果图长这样:
我已经提了<template>
<input ref="el" />
</template>issue,看下作者是否同意改造成<template>
<input ref="el" />
</template>TS,同意的话,我立马就是一个<template>
<input ref="el" />
</template>PR<template>
<input ref="el" />
</template>过去!
话不多说,大家有需要的,可直接拿走!
《JS<template>
<input ref="el" />
</template>项目改造成<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目指南》


JS<template>
<input ref="el" />
</template>项目改造成<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>步骤:

  • 安装<template>
    <input ref="el" />
    </template>TS:npm<template>
    <input ref="el" />
    </template>i<template>
    <input ref="el" />
    </template>typescript<template>
    <input ref="el" />
    </template>ts-loader<template>
    <input ref="el" />
    </template>-D
  • 增加<template>
    <input ref="el" />
    </template>TS<template>
    <input ref="el" />
    </template>配置文件:tsconfig.json
  • 修改文件后缀名:x.js<template>
    <input ref="el" />
    </template>-><template>
    <input ref="el" />
    </template>x.ts
  • x.vue<template>
    <input ref="el" />
    </template>文件增加<template>
    <input ref="el" />
    </template>lang:<script<template>
    <input ref="el" />
    </template>lang="ts">
  • vite.config.js<template>
    <input ref="el" />
    </template>配置后缀名
  • 升级依赖,修改本地启动和构建脚本
  • 添加<template>
    <input ref="el" />
    </template>loader<template>
    <input ref="el" />
    </template>/<template>
    <input ref="el" />
    </template>plugin<template>
    <input ref="el" />
    </template>等
  • 逐步补充类型声明
tsconfig.ts
  1. {<template>
  2. <input ref="el" />
  3. </template>"compilerOptions":<template>
  4. <input ref="el" />
  5. </template>{<template>
  6. <input ref="el" />
  7. </template>"target":<template>
  8. <input ref="el" />
  9. </template>"ESNext",<template>
  10. <input ref="el" />
  11. </template>"useDefineForClassFields":<template>
  12. <input ref="el" />
  13. </template>true,<template>
  14. <input ref="el" />
  15. </template>"module":<template>
  16. <input ref="el" />
  17. </template>"ESNext",<template>
  18. <input ref="el" />
  19. </template>"moduleResolution":<template>
  20. <input ref="el" />
  21. </template>"Node",<template>
  22. <input ref="el" />
  23. </template>"strict":<template>
  24. <input ref="el" />
  25. </template>true,<template>
  26. <input ref="el" />
  27. </template>"jsx":<template>
  28. <input ref="el" />
  29. </template>"preserve",<template>
  30. <input ref="el" />
  31. </template>"sourceMap":<template>
  32. <input ref="el" />
  33. </template>true,<template>
  34. <input ref="el" />
  35. </template>"resolveJsonModule":<template>
  36. <input ref="el" />
  37. </template>true,<template>
  38. <input ref="el" />
  39. </template>"isolatedModules":<template>
  40. <input ref="el" />
  41. </template>true,<template>
  42. <input ref="el" />
  43. </template>"esModuleInterop":<template>
  44. <input ref="el" />
  45. </template>true,<template>
  46. <input ref="el" />
  47. </template>"lib":<template>
  48. <input ref="el" />
  49. </template>["ESNext",<template>
  50. <input ref="el" />
  51. </template>"DOM"],<template>
  52. <input ref="el" />
  53. </template>"skipLibCheck":<template>
  54. <input ref="el" />
  55. </template>true<template>
  56. <input ref="el" />
  57. </template>},<template>
  58. <input ref="el" />
  59. </template>"include":<template>
  60. <input ref="el" />
  61. </template>[<template>
  62. <input ref="el" />
  63. </template>"src/**/*.ts",<template>
  64. <input ref="el" />
  65. </template>"src/**/*.d.ts",<template>
  66. <input ref="el" />
  67. </template>"src/**/*.tsx",<template>
  68. <input ref="el" />
  69. </template>"src/**/*.vue"<template>
  70. <input ref="el" />
  71. </template>]}
复制代码
配置文件后缀名,增加<template>
<input ref="el" />
</template>.ts<template>
<input ref="el" />
</template>和<template>
<input ref="el" />
</template>.tsx
  1. extensions:<template>
  2. <input ref="el" />
  3. </template>['.js',<template>
  4. <input ref="el" />
  5. </template>'.vue',<template>
  6. <input ref="el" />
  7. </template>'.json',<template>
  8. <input ref="el" />
  9. </template>'.ts',<template>
  10. <input ref="el" />
  11. </template>'tsx'],入口文件要由<template>
  12. <input ref="el" />
  13. </template>main.js<template>
  14. <input ref="el" />
  15. </template>改成<template>
  16. <input ref="el" />
  17. </template>main.tsentry:<template>
  18. <input ref="el" />
  19. </template>{<template>
  20. <input ref="el" />
  21. </template><template>
  22. <input ref="el" />
  23. </template>app:<template>
  24. <input ref="el" />
  25. </template>'./src/main.ts'},
复制代码
需要配置下<template>
<input ref="el" />
</template>loader
  1. {<template>
  2. <input ref="el" />
  3. </template><template>
  4. <input ref="el" />
  5. </template>test:<template>
  6. <input ref="el" />
  7. </template>/\.tsx?$/,<template>
  8. <input ref="el" />
  9. </template><template>
  10. <input ref="el" />
  11. </template>loader:<template>
  12. <input ref="el" />
  13. </template>'ts-loader',<template>
  14. <input ref="el" />
  15. </template><template>
  16. <input ref="el" />
  17. </template>exclude:<template>
  18. <input ref="el" />
  19. </template>/node_modules/,<template>
  20. <input ref="el" />
  21. </template><template>
  22. <input ref="el" />
  23. </template>options:<template>
  24. <input ref="el" />
  25. </template>{<template>
  26. <input ref="el" />
  27. </template>appendTsSuffixTo:<template>
  28. <input ref="el" />
  29. </template>[/\.vue$/]<template>
  30. <input ref="el" />
  31. </template>},<template>
  32. <input ref="el" />
  33. </template><template>
  34. <input ref="el" />
  35. </template>include:<template>
  36. <input ref="el" />
  37. </template>[resolve('src')]}
复制代码
以及<template>
<input ref="el" />
</template>plugin
  1. const<template>
  2. <input ref="el" />
  3. </template>{<template>
  4. <input ref="el" />
  5. </template>VueLoaderPlugin<template>
  6. <input ref="el" />
  7. </template>}<template>
  8. <input ref="el" />
  9. </template>=<template>
  10. <input ref="el" />
  11. </template>require('vue-loader')plugins:<template>
  12. <input ref="el" />
  13. </template>[<template>
  14. <input ref="el" />
  15. </template>new<template>
  16. <input ref="el" />
  17. </template>VueLoaderPlugin()],
复制代码
完成之后,先测试下项目是否能正常启动和构建:npm<template>
<input ref="el" />
</template>run<template>
<input ref="el" />
</template>dev<template>
<input ref="el" />
</template>/<template>
<input ref="el" />
</template>npm<template>
<input ref="el" />
</template>run<template>
<input ref="el" />
</template>build
都没问题之后,本次<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>项目改造就完成大部分啦啦!
后续就是逐步补充代码涉及到的变量和函数的类型声明即可。
改造过程中遇到问题欢迎留言讨论,希望你也能尽快享受<template>
<input ref="el" />
</template>TS<template>
<input ref="el" />
</template>的丝滑开发者体验!
TinyVue<template>
<input ref="el" />
</template>招募贡献者啦


如果你对我们的跨端跨框架组件库 TinyVue 感兴趣,欢迎参与到我们的开源社区中来,一起将它建设得更好!
参与<template>
<input ref="el" />
</template>TinyVue<template>
<input ref="el" />
</template>组件库建设,你将收获:
直接的价值:

  • 通过打造一个跨端、跨框架的组件库项目,学习最新的<template>
    <input ref="el" />
    </template>Monorepo<template>
    <input ref="el" />
    </template>+<template>
    <input ref="el" />
    </template>Vite<template>
    <input ref="el" />
    </template>+<template>
    <input ref="el" />
    </template>Vue3<template>
    <input ref="el" />
    </template>+<template>
    <input ref="el" />
    </template>TypeScript<template>
    <input ref="el" />
    </template>技术
  • 学习从<template>
    <input ref="el" />
    </template>0<template>
    <input ref="el" />
    </template>到<template>
    <input ref="el" />
    </template>1<template>
    <input ref="el" />
    </template>搭建一个自己的组件库的整套流程和方法论,包括组件库工程化、组件的设计和开发等
  • 为自己的简历和职业生涯添彩,参与过优秀的开源项目,这本身就是受面试官青睐的亮点
  • 结识一群优秀的、热爱学习、热爱开源的小伙伴,大家一起打造一个伟大的产品
长远的价值:

  • 打造个人品牌,提升个人影响力
  • 培养良好的编码习惯
  • 获得华为云<template>
    <input ref="el" />
    </template>OpenTiny<template>
    <input ref="el" />
    </template>开源社区的荣誉&认可和定制小礼物
  • 成为<template>
    <input ref="el" />
    </template>PMC<template>
    <input ref="el" />
    </template>&<template>
    <input ref="el" />
    </template>Committer<template>
    <input ref="el" />
    </template>之后还能参与<template>
    <input ref="el" />
    </template>OpenTiny<template>
    <input ref="el" />
    </template>整个开源生态的决策和长远规划,培养自己的管理和规划能力。
  • 未来有更多机会和可能
往期活动礼品及贡献者的反馈:
联系我们

如果你对我们<template>
<input ref="el" />
</template>OpenTiny<template>
<input ref="el" />
</template>的开源项目感兴趣,欢迎添加小助手微信:opentiny-official,拉你进群,一起交流前端技术,一起玩开源。
OpenTiny<template>
<input ref="el" />
</template>官网:https://opentiny.design/
OpenTiny<template>
<input ref="el" />
</template>仓库:https://github.com/opentiny/

Vue<template>
<input ref="el" />
</template>组件库:https://github.com/opentiny/tiny-vue(欢迎<template>
<input ref="el" />
</template>Star<template>
<input ref="el" />
</template>
来源:https://www.cnblogs.com/huaweiyun/p/17302482.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】<template>
<input ref="el" />
</template>我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具