Giter Site home page Giter Site logo

blog's Introduction

Hi there 👋

🐠 I’m scTaoFelix.

blog's People

Contributors

sctao avatar

Watchers

 avatar

blog's Issues

Git 基础

1.获取一个仓库

创建一个 git 仓库

  • git init
    该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。
$ git init # 在当前目录新建一个 Git代码库
$ git init [project-name] # 新建一个目录,将其初始化为 Git代码库

克隆现有的仓库

  • git clone
    Git 克隆的是该 Git 仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。 当你执行 git clone 命令的时候,默认配置下远程 Git 仓库中的每一个文件的每一个版本都将被拉取下来。
$ git clone <url>
$ git clone <url> myRepoName # 克隆远程仓库 并自定义本地仓库的名字

配置

Git的设置文件为.gitconfig ,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

  1. /etc/gitconfig/usr/local/etc/gitconfig)文件: 包含系统上每一个用户及他们仓库的通用配置。 如果在执行 git config 时带上 --system 选项,那么它就会读写该文件中的配置变量。 (由于它是系统配置文件,因此你需要管理员或超级用户权限来修改它。)

  2. ~/.gitconfig~/.config/git/config 文件:只针对当前用户。 你可以传递 --global 选项让 Git 读写此文件,这会对你系统上 所有 的仓库生效。

  3. 当前使用仓库的 Git 目录中的 config 文件(即 .git/config):针对该仓库。 你可以传递 --local 选项让 Git 强制读写此文件,虽然默认情况下用的就是它。。 (当然,你需要进入某个 Git 仓库中才能让该选项生效。)

$ git config --list # 显示当前的Git配置
$ git config --list --show-origin # 显示当前的Git配置及文件位置

$ git config -e [--global] # 编辑Git配置文件
# 配置 名称和邮箱
$ git config --global user.name "John Doe"
$ git config --global user.email [email protected]

e.g:
比如你有个公司的 gitLab 和你自己的 gitHub
你可以 把全局的设置为 公司的邮箱账号,而你自己的 gitHub 则用仓库中的 config。
你可以在你的仓库里运行以下命令:

# --local
$ git config user.name "John" 
$ git config user.email "[email protected]" 

2.提交相关

首先我们要知道文件的状态只会有两种:已跟踪未跟踪

  • 已跟踪:未修改已修改已放入暂存区
  • 未跟踪:不会被 git 记录, 使用 git add 添加到已跟踪文件
$ git add <files> # 跟踪新文件
$ git add * # 添加当前目录的所有文件到暂存区(包含 .gitignore 过滤的文件) -f
$ git add . # 添加当前目录的所有文件到暂存区(不包含 .gitignore 过滤的文件)
$ git add -p # 对于同一个文件的多处变化,可以实现分次提交

作用:

  1. 跟踪新文件
  2. 把已跟踪的文件放到暂存区
  3. 还能用于合并时把有冲突的文件标记为已解决状态等

检查当前文件状态

git status 命令查看哪些文件处于什么状态

$ git status
$ git status -s / --short 精简

忽略文件

.gitignore:列出要忽略的文件的模式

# 查看 .gitignore 文件内容
$ cat .gitignore

*.a # 忽略所有的 .a 文件
*.[oa] # 忽略所有以 .o 或 .a 结尾的文件
*~ # 忽略所有名字以波浪符(~)结尾的文件

!lib.a # 跟踪所有的 lib.a,虽然上面忽略了 .a 文件

/TODO # 只忽略当前目录下的 TODO 文件
build/ # 忽略任何目录下名为 build 的文件夹

doc/*.txt # 只忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/**/*.pdf # 忽略 doc/ 目录及其所有子目录下的 .pdf 文件

gitignore 例子
文件 .gitignore 的格式规范如下:

  • 所有空行或者以 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
  • 匹配模式可以以(/)开头防止递归。
  • 匹配模式可以以(/)结尾指定目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反。

glob 模式是指 shell 所使用的简化了的正则表达式。

在最简单的情况下,
一个仓库可能只根目录下有一个 .gitignore 文件,它递归地应用到整个仓库中。
子目录下也可以有额外的 .gitignore 文件。子目录中的 .gitignore 文件中的规则只作用于它所在的目录中。

查看已暂存和未暂存的修改

  • 查看尚未暂存文件的修改
$ git diff
  • 已暂存文件与最后一次提交的文件差异:
$ git diff --staged (--cached) [file]
其他 diff 用法
  • 显示工作区与当前分支最新 commit 之间的差异
$ git diff HEAD
  • 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]

提交更新

$ git commit -v # 提交时显示所有 diff信息
$ git commit # 不加参数会掉起 Vim 的编辑方式

Vim 的编辑方式展示:

vim

开头第一行是个空行,供你输入提交说明(我输入的是 init repo)。
默认的提交消息放在注释行里,退出编辑器时,Git 会丢弃注释行,用你输入的提交说明生成一次提交。

$ git commit -m"将提交信息与命令放在同一行"
[master 2a4e415] init repo
 1 file changed, 1 insertion(+)

提交后它会告诉你,当前是在哪个分支(master)提交的,本次提交的完整 SHA-1 校验和是什么(2a4e415),以及在本次提交中,有多少文件修订过,多少行添加和删改过。

跳过使用暂存区域

$ git commit -a -m "跳过 git add 步骤"
# 等于
$ git add *
$ git commit -m "xxx"

此命令会将你工作区所有的更改都添加到提交中。

移除文件

从暂存区移除 & 在工作目录删除

  • 从暂存区移除文件,并在工作目录中也删除这个文件。
# 已提交的文件
$ git rm PROJECTS.md

# 工作区修改过或已经放到暂存区
$ git rm file.name -f (--force)

下一次提交时,该文件就不再纳入版本管理了。只需 git commit 提交(无需 git add)。

从暂存区移除

  • 你想让文件保留在磁盘,但是并不想让 Git 继续跟踪
$ git rm --cached file.name
# 使用 glob 模式: 删除 log/ 目录下扩展名为 .log 的所有文件。
$ git rm log/\*.log

移动文件

# 直接保存到了暂存区
$ git mv file_from.md file_to.md

# 等于
$ mv file_from.md file_to.md
$ git rm file_from.md
$ git add file_to.md

# 或者
$ mv file_from.md file_to.md
$ git add *

3.查看提交历史

$ git log
commit 2a4e4157641a858034dffab06b5c8f9a88b02c00 (HEAD -> master)
Author: sc <[email protected]>
Date:   Sun Oct 10 15:30:55 2021 +0800

    delete file
commit be2150139fad2740995d3ddccf7089fcc41fce2b
Author: sc <[email protected]>
Date:   Sun Oct 10 15:27:24 2021 +0800

    init repo
  • git log -p 或 --patch (它会显示每次提交所引入的差异(按 补丁 的格式输出))
$ git log -p -2 (-2代表选项来只显示最近的两次提交)

# 每次提交的简略统计信息
$ git log --stat -2

#(short,full 和 fuller)
$ git log --pretty=oneline 
a16782d70db6c254004aed029433c2636a697aa7 (HEAD -> master) 最后的提交
85075a97cc9a0b8fa358df5c5fc29e9da1f0a057 log

来看一个实际的例子,如果要在 Git 源码库中查看 scTaoFelix 在 2020-10-01 到 2021-10-01其间, 除了合并提交之外的提交,可以使用下面的命令:

$ git log --pretty="%h - %s" --author='scTaoFelix <[email protected]>' --since="2020-10-01" --before="2021-10-01" --no-merges     

  • git log 的常用选项
选项 说明
-p 按补丁格式显示每个提交引入的差异。
--stat 显示每次提交的文件修改统计信息。
--shortstat 只显示 --stat 中最后的行数修改添加移除统计。
--name-only 仅在提交信息后显示已修改的文件清单。
--name-status 显示新增、修改、删除的文件清单。
--abbrev-commit 仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。
--relative-date 使用较短的相对时间而不是完整格式显示日期(比如“2 weeks ago”)。
--graph 在日志旁以 ASCII 图形显示分支与合并历史。
--pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。
--oneline --pretty=oneline --abbrev-commit 合用的简写。
$ git log --pretty=format:"%h - %an, %ar : %s"
a16782d - sc, 11 分钟前 : 最后的提交
85075a9 - sc, 12 分钟前 : git log

--pretty=format

$ git log --pretty=format:"%h %s" --graph

image

  • git log --pretty=format 常用选项
选项 说明
%H 提交的完整哈希值
%h 提交的简写哈希值
%T 树的完整哈希值
%t 树的简写哈希值
%P 父提交的完整哈希值
%p 父提交的简写哈希值
%an 作者名字
%ae 作者的电子邮件地址
%ad 作者修订日期(可以用 --date=选项 来定制格式)
%ar 作者修订日期,按多久以前的方式显示
%cn 提交者的名字
%ce 提交者的电子邮件地址
%cd 提交日期
%cr 提交日期(距今多长时间)
%s 提交说明

限制输出长度

--since,--after - 仅显示指定时间之后的提交(不包含当前日期)
--until,--before - 仅显示指定时间之前的提交(包含当前日期)

# 查看从 2021-09-18 之后到 3周前的提交
$ git log --pretty="%h - %s"  --before={3,weeks,ago} --after={2021-09-18}
$ git log --since=2.weeks
  • 常用选项
选项 说明
-<n> 仅显示最近的 n 条提交。
--since, --after 仅显示指定时间之后的提交。
--until, --before 仅显示指定时间之前的提交。
--author 仅显示作者匹配指定字符串的提交。
--committer 仅显示提交者匹配指定字符串的提交。
--grep 仅显示提交说明中包含指定字符串的提交。
-S 仅显示添加或删除内容匹配指定字符串的提交。

4.撤消操作

重置 commit

$ git commit --amend

有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了

  • 自上次提交以来你还未做任何修改: 只修改提交信息
  • 漏掉了几个文件没有添加,如下:
# 最终你只会有一个提交——第二次提交将代替第一次提交的结果。
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

最终你只会有一个提交——第二次提交将代替第一次提交的结果。

取消暂存的文件

  • git restore --staged <file>... 将文件从暂存区撤出,但不会撤销文件的更改(git reset HEAD <file>...

撤消对文件的修改

  • git resore <file>... 将不在暂存区的文件撤销更改, git checkout -- readme.md 也有相同的作用

image
image

在 Git 中任何 已提交 的东西几乎总是可以恢复的。 甚至那些被删除的分支中的提交或使用 --amend 选项覆盖的提交也可以恢复。 然而任何你未提交的东西丢失后很可能再也找不到了。

5.远程仓库的使用

$ git remote
origin
# 列出所有的远程仓库
$ git remote -v
origin	xxx (fetch)
origin	xxx (push)
  • 添加远程仓库
    git remote add <shortname> <url>
  • 从远程仓库中抓取与拉取
    $ git fetch <remote>
  • 推送到远程仓库
    $ git push origin master
  • 查看某个远程仓库
    $ git remote show origin
  • 远程仓库的重命名与移除
    $ git remote rename old_name new_name
    $ git remote remove origin 或 git remote rm origin

6.打标签

列出标签

git tag (可带上可选的 -l 选项 --list):

$ git tag # 列出所有tag
v1.0
v2.0

$ git tag -l "v1.8.5*" 匹配标签名的通配模式

创建标签

Git 支持两种标签:轻量标签(lightweight)与附注标签(annotated)。

  • 轻量标签很像一个不会改变的分支——它只是某个特定提交的引用。
  • 附注标签是存储在 Git 数据库中的一个完整对象, 它们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard (GPG)签名并验证。

附注标签

$ git tag -a v1.4 -m "my version 1.4"
$ git tag
v0.1
v1.3
v1.4

通过使用 git show 命令可以看到标签信息和与之对应的提交信息:

 git show v1.4

轻量标签
轻量标签本质上是将提交校验和存储到一个文件中——没有保存任何其他信息。 创建轻量标签,不需要使用 -a、-s 或 -m 选项,只需要提供标签名字:

$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5

给某个 commitID 打标签

$ git tag -a v1.2 commitID

新建一个分支,指向某个 tag

$ git checkout -b [branch] [tag]

共享标签

默认情况下,git push 命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。 这个过程就像共享远程分支一样——你可以运行 git push origin 。

$ git push <remote> --tags # 推送所有tag
$ git push [remote] [tag] # 推送某个tag
# git push origin v1.5 

删除标签

要删除掉你本地仓库上的标签,可以使用命令

 git tag -d <tagname> # 删除本地tag
 git push <remote> :refs/tags/<tagname> # 删除远程tag
 # git push origin :refs/tags/v1.4-lw
git push origin --delete v1.0 
# 删除远程标签,git push origin :v1.0 
# git push origin :refs/tags/v1.0

Git 本地配置别名

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

TS 在业务侧的使用

1.Typescript 的设计初衷

随着硬件性能、前端自身快速发展等因素,前端应用程序的体量与复杂度直线上升。

在大型应用的开发过程中,随着开发人员数量的增加、代码体量的增长、业务场景复杂度的上升,文档及单元测试的不完整等情况的出现。

使得 JavaScript 动态语言与弱类型的语言特性暴露了以下问题:

  1. 类型错误多。
  2. 缺少文档、新成员理解应用逻辑困难。
  3. 维护成本高、可扩展性差的困境。

并且在一个项目开发中,随着需求的变化和代码体量的增长,我们的项目不可避免地会趋于复杂,最终造成了项目中后期进度缓慢的情形 。如何对项目复杂度及其增长速率进行有效控制,便成为一个日益突出的问题。而 Typescript 正是在这种情况下,应运而生的。

Typescript 的维基百科词条

  • TypeScript 起源于 Javascript 在微软以及客户中开发大型应用中遇到的缺点。处理复杂 JavaScript 代码带来的挑战使他们需要自定义工具来简化组件开发流程。
  • TypeScript 开发者寻求一种不破坏现有标准兼容性和跨平台支持的解决方案。知道ECMAScript标准为未来基于类编程提供支持后, Typescript开发便基于此方案。这形成了包含一组新的语法扩展的一个JavaScript 编译器,一个基于此提案的超集,可将TypeScript语法编译为常规的JavaScript。
  • TypeScript 不仅包含 JavaScript 的语法,而且还提供了静态类型检查以及使用看起来像基于类的面向对象编程语法操作 Prototype。

2.Typescript 的两大特性

静态类型检查、面向对象

静态类型检查
rollbar 是一个异常监控平台,rollbar 于 2018 年统计了前端项目中Top10 的错误类型

下图统计同一个错误在多少个项目中出现,并以此来排序。
77267185-5a7d112d12e2c_fix732

其中有 7 个是类型错误(TypeError):

  1. Cannot read property 'xxx' on undefined: 无法在 undefined 上读取 xxx 属性,通常出现在 a.b.c 的情况。
  2. 'undefined' is not an object: undefined 不是对象 (Safari ,同 1)
  3. null is not an object: null 不是对象(Safari)
  4. 'undefined' is not a function: undefined 不是函数,通常出现在 a.b.c() 的情况。
  5. Object doesn't support property IE 中调用未定义的方法,同 4
  6. Cannot read property 'length': 无法读取 'length' 属性,本来期望一个数组,但是变量的实际类型却不是数组。
  7. cannot set property of undefined: 无法给 undefined 设置属性。
  8. TypeScript 提供的编译期类型检查可以解决上面 TypeError 的问题。

怎么解决,举一个例子:

假如你写了一个 utils 方法 sayName:

function sayName(dog) {
  return dog.sayName()
}

作为调用方调用:

// 在javascript中调用报错
// Uncaught TypeError: dog.sayName is not a function
sayName("dog")

看过前面的函数定义,我们知道以上代码不出意外会报错,因为 dog 字符串没有 sayName 方法。

实际情况中,函数定义对于调用者而言是一个黑盒,错误的调用成为了大概率事件,可怕的是开发阶段你完全觉察不到错误的存在。

为了解决这个问题,我们用 typescript 为 dog 参数提供了类型描述 dogType.

// DogType 描述了一个包含 sayName 方法的类型
type DogType = {
  sayName: ()=> void;
};
function sayName(dog: DogType) {
  return dog.sayName()
}


// 以下代码在 typescript 中调用报错(vscode)
// 类型“string”的参数不能赋给类型“DogType”的参数。ts(2345)
sayName('dog')

面向对象
封装、继承、多态。

  • 封装:隐藏数据和功能实现细节,避免被外部修改,而导致误用。
  • 继承:子类拥有父类的所有属性和方法,从而实现了实现代码的复用。
  • 多态:同一个行为具有多个不同表现形式或形态的能力。
// 继承:子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
// 多态:由继承而产生了相关的不同的类,对同一个方法可以有不同的响应

class Animal {
  speak(word: string): string {
      return 'Animal: ' + word
  }
}


class Cat extends Animal {
  speak(word: string): string {
      return 'Cat: ' + word
  }
}

class Dog extends Animal {
  speak(word: string): string {
      return 'Dog: ' + word
  }
}

let cat = new Cat()
console.log(cat.speak('hello'))
let dog = new Dog()
console.log(dog.speak('hello'))

还有一个 typeof class 的注意点:
typeof class 和直接用 class 作为类型有什么区别,改写一下 Animale:

class Animal {
  static message = ' world'
  speak(word: string): string {
    return 'Animal: ' + word + Animal.message
  }
}



// 获取的是实例的类型,该类型可以获取实例对象上的属性/方法
let animal1: Animal = new Animal()
console.log(animal1.speak('hello')) // 'Animal: hello world'


// 获取的是类的类型,该类型可以获取类上面的静态属性/方法
let animalTwo: typeof Animal = Animal
animalTwo.message = ' humen'

let animal2: Animal = new animalTwo()
console.log(animal2.speak('hello')) // 'Animal: hello humen'

3.Typescript 为我们带了什么(收益)

3.1 类型错误的静态检查和定位:

3-TS

3.2 阅读代码能力的加持:

1.智能类型提示:如果库支持 ts 那么就会有很好的提示
4
5

  • 代码可阅读性的提高
  • 编写速度的加快
  • 可维护性的提高
  • 可以更安全的进行重构

Typescript是如何解决上述问题的?

  1. 静态类型检查可以尽早构建失败。一旦编写代码时发生类型不匹配,在编译阶段发现,不用等到运行时。
  2. 静态类型对阅读代码是友好的。针对大型应用,方法众多,调用关系复杂,不可能每个函数都有人编写细致的文档,所以静态类型就是非常重要的提示和约束。
  3. 借助面向的设计**,隐藏实现细节,加强功能的内聚性。控制接口暴露粒度,来降低功能间的耦合度,达到容易扩展的效果。
  4. 静态类型其配合 IDE 的重构功能,维护困难系数直线下降。

4.ts 在业务侧的特点

优点:

  1. TypeScript 在你写代码的过程中就能发现错误,不用等到运行时。
  2. TypeScript 是强类型语言的特性,强制定义各种数据的类型,可读性强
  3. 不改变运行时行为
  4. 提供很好的的拼写检查和智能提示,可以用 ts 给变量或参数限定类型,用来规避 js 默认的隐式转换带来的一些困扰。
  5. 类型就是最好的注释

缺点:

  1. 使用初期会比较麻烦
  2. 学习曲线陡峭

5.如何减少业务侧 升级到 ts 成本:
1.首先 升级到 ts 是一个渐进的过程

  1. 共存策略
  2. 宽松策略
  3. 严格策略

所以如果我们想使用TS 应该从 共存策略 开始,

共存策略: 即 JS 和 TS 共存,存在的 JS 文件,我们还可以配置 checkJs 决定对 js 文件是否进行类型检查。

{
  "compilerOptions": {
    "allowJs": true
	// "checkJs": true,
  }
}

宽松策略: 没有 JS 文件,但类型检查使用最宽松的模式。

{
  "compilerOptions": {
    "allowJs": fase,
	"checkJs": false,
	"strict": false
  }
}

严格策略: 没有 JS 文件且 strict 为 true。

{
  "compilerOptions": {
	"strict": true
  }
}

升级过程中的问题: 依赖也需要升级

如果你的依赖 是 JS 库,默认 TS 也不会报错。因为没有声明文件的 JS 模块会隐式的获得any类型,除非 tsconfig.json 中配置了 noImplicitAny: true ,指明了如有隐式转换为 any 类型就报错,才会报错。

当然你也可以使用 使用第三方类库github 地址

6.社区发展:
前端在经过 Flow、Typescript、CoffeeScript 等短暂的类型检查之争后。Typescript 在开发速度、协作成本、维护成本上的出色表现,实践过 Typescript 构建大型应用的团队,几乎是一边倒的从JS转向了 TS。具有代表性的:Ant-design、Angular、Vue-next 从最初的 JS 版本切换到了 TS 版本。包括

看一下最近一年 typescript 的npm 包下载量。更多:npm-stat
2-ts
2020-11-10 到 2021-11-10 的下载量:

package downloads
typescript 984,454,322

7.我遇到的问题(成本)

刚开始使用时,遇到的这些问题,都算是成本,但是解决之后,就变成我们的收益。

1.window 下 setTimeoout 的类型 问题

// 不能将类型“Timeout”分配给类型“number”。ts(2322)
let timer = 0
timer = setTimeout(() => {
	console.log(10)
})


跳转到定义 发现setTimeout使用的是 Node.js 下的接口定义
// @types/node timer.d.ts
function setTimeout<TArgs extends any[]>(callback: (...args: TArgs) => void, ms?: number, ...args: TArgs): NodeJS.Timeout;


而在 typescript 中,window 下的 setTimeout 返回的是 number:


interface WindowOrWorkerGlobalScope {
    ...
    clearInterval(handle?: number): void;
    clearTimeout(handle?: number): void;
    setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
    setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;
}


所以我们要改成
timer = window.setTimeout(() => {
	console.log(10)
})

2.扩展全局模块上的属性时,TypeScript 会报属性不存在

fusion

当我们需要扩展某个全局模块时: ```js // 有具体类型时 import FusionClass from '@didi/fusion' declare global { interface Window { Fusion: FusionClass } } // 或者 declare interface Window { Fusion: any } ``` #### 3.建议开启 [strictNullChecks](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#strictnullchecks-on) 默认情况下,null 和 undefined 是其它类型的子类型,可以赋值给其它类型,如number类型,此时,赋值后的类型会变成 null 或 undefined。 ```js // 启用 strictNullChecks: true let x: number; x = 1; // 运行正确 x = undefined; // 运行错误 x = null; // 运行错误 ``` 我在使用时遇到的问题: ```js type fn = Function | undefined

// strictNullChecks:false
type final = fn extends Function ? 1 : 2 // 1 因为 undefined 可以赋值给 Function 类型。

// strictNullChecks:true
type final = fn extends Function ? 1 : 2 // 2

#### 4.指定 target 为 es6 时,tsc 就会默认使用 ["classic" 模块解析策略](https://www.typescriptlang.org/docs/handbook/module-resolution.html),这个策略对于非相对路径的导入,不能正确解析。
```js
 import { dbridge, IDBridge } from '@didi/driver-bridge'
// 找不到模块“@didi/driver-bridge”。你的意思是要将 "moduleResolution" 选项设置为 "node",还是要将别名添加到 "paths" 选项中?ts(2792)


// 我们可以 在 tsconfig.ts 里配置一下
{
  "compilerOptions": {
    "target": "es6",
    "moduleResolution": "node"
   }
}

5.引入JSON文件的配置:resolveJsonModule
6

// tsconfig.ts {   "compilerOptions": {     "resolveJsonModule": true    } }
{
  "compilerOptions": {
    "resolveJsonModule": true
   }
}

这样就可以引入 json 文件了

8.其他

1.为什么浏览器不直接支持typescript?

因为TypeScript的性能太差了。

首先TypeScript需要类型检查,而类型检查就需要先把所有的源代码都下载完毕之后才能进行,毕竟编译器也不知道你引用的库究竟在什么文件中,甚至还要下载毫无用处的 d.ts 文件,这个只是纯粹的类型声明文件,对于程序的正常运行毫无帮助,额外的增加了流量支出。

2.ts 使用的一些建议:

1.interface 和 type 关键字

  • interface 和 type 两个关键字因为其功能比较接近,常常引起新手的疑问:应该在什么时候用 type,什么时候用 interface?

interface 的特点如下:

  • 同名 interface 自动聚合,也可以和已有的同名 class 聚合,适合做 polyfill
  • 自身只能表示 object/class/function 的类型
  • 建议库的开发者所提供的公共 api 应该尽量用 interface/class,方便使用者自行扩展。

与 interface 相比,type 的特点如下:

  • 表达功能更强大,不局限于 object/class/function
  • 要扩展已有 type 需要创建新 type,不可以重名
  • 支持更复杂的类型操作

2.类型断言

一般只有这几种场景需要使用类型转换:自动推断不准;TS 报错,想不出更好的类型编写方法;临时使用;

类型转换的语法为 < 类型名> xxx 或 xxx as 类型名。

推荐始终用 as 语法,因为第一种语法无法在 tsx 文件使用,而且容易和泛型混淆。

3.类型体操
type-challenges

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.