Giter VIP home page Giter VIP logo

typescript-book-chinese's Introduction

深入理解 TypeScript

All Contributors GitHub forks GitHub stars GitHub issues GitHub last commit PRs Welcome

此书是 《TypeScript Deep Dive》 的中文翻译版,感谢作者 Basarat 的付出。

如果你喜欢纸质书籍,可以通过京东或者当当,来购买此书。

你可以通过订阅该公众号,来获取更多有趣的内容。

Why

downloads

数据来源:npm 包下载量

如你所见,TypeScript 发展至今,已经成为大型项目的标配,其提供的静态类型系统,大大增强了代码的可读性以及可维护性;同时,它提供最新和不断发展的 JavaScript 特性,能让我们建立更健壮的组件。

《TypeScript Deep Dive》 是一本很好的开源书,从基础到深入,很全面的阐述了 TypeScript 的各种魔法,不管你是新手,还是老鸟,它都将适应你。此外,它不同于 TypeScript 官方给出的文档(当然 TypeScript 给出的文档是很好的),在此书中,结合实际应用下的场景用例,你将能更深入的理解 TypeScript。

如今社区已经存在部分翻译,但都似乎已经停止更新。

于是在某天的某个冲动之下,这个 RP 就诞生了。

翻译内容

《TypeScript Deep Dive》 书中包含一部分 JavaScript Future 和一些其他的内容,在这里,我们并不打算翻译它,如果你有兴趣,可以查看原书中 JavaScript Future 的有关章节。

由于 TypeScript 更新频繁,除了上文中提到翻译部分,将会加入 TypeScript 的 Release,同时我也将总结出工作中一些有意思的点,希望和大家相互学习,一起进步。

此外,在不违背原作者本意前提下,为了更直观的表达,部分内容将采用意译,而非直译。

Contributors

Thanks goes to these wonderful people (emoji key):

三毛
三毛

📖
KnorienChang
KnorienChang

📖
阿卡琳
阿卡琳

📖
hopalay
hopalay

📖
Xing Liu
Xing Liu

📖
chenwangji
chenwangji

📖
老农爱盐碱地
老农爱盐碱地

📖
Necros
Necros

📖
Xu Jihan
Xu Jihan

📖
Yu
Yu

📖
Yoga Lin
Yoga Lin

📖
G
G

📖
Undrum
Undrum

📖
Zong
Zong

📖
LXVC
LXVC

📖
Whale
Whale

📖
getdaydream
getdaydream

📖
Ling ZiQing
Ling ZiQing

📖
izayl
izayl

📖
Moorez
Moorez

📖
萤火之未
萤火之未

📖
xfields
xfields

📖
ZhaZheng
ZhaZheng

📖
弘树@阿里
弘树@阿里

📖
wangjingchao
wangjingchao

📖
IWANABETHATGUY
IWANABETHATGUY

📖
Payton Tang
Payton Tang

📖
Rem486
Rem486

📖
Steve Young
Steve Young

📖
olive.wang
olive.wang

📖
Rainy
Rainy

📖
随风
随风

📖
大板栗
大板栗

📖
Superman
Superman

📖
Payton Deng
Payton Deng

📖
Wang Kang
Wang Kang

📖
wuchouchou
wuchouchou

📖
EastblueOkay
EastblueOkay

📖
Nic
Nic

📖
重庆崽儿Brand
重庆崽儿Brand

📖
YanYuan
YanYuan

📖
JunaYa
JunaYa

📖
黎聪
黎聪

📖
WANGXUEFENG
WANGXUEFENG

📖
Xiaohan Li
Xiaohan Li

📖
dingkang
dingkang

📖
zhangciwu
zhangciwu

📖
Jack
Jack

📖
masterZSH
masterZSH

📖
Eve
Eve

📖
Xuemuyang
Xuemuyang

📖
Jasery
Jasery

📖
Baskerville*
Baskerville*

📖
FishPlusOrange
FishPlusOrange

📖
月迷津渡
月迷津渡

📖
evinma
evinma

📖
Suyan
Suyan

📖
cherry-man
cherry-man

📖
蔡南坤
蔡南坤

📖
chenc
chenc

📖
Xinxing Li
Xinxing Li

📖
GuangHui
GuangHui

📖
odzcdut
odzcdut

📖
项鸿伟
项鸿伟

📖
xiezhichao
xiezhichao

📖
Charles
Charles

📖
Jexxie
Jexxie

📖
Sean Wong
Sean Wong

📖
bluelovers
bluelovers

📖
Celery
Celery

📖
chenxiaochun
chenxiaochun

📖
Yates
Yates

📖
IGoR
IGoR

📖
byog
byog

📖
whincwu
whincwu

📖
康东扬
康东扬

📖
Kenny
Kenny

🚇
AllenLee
AllenLee

📖
xiangming25
xiangming25

📖
Chanvin Xiao
Chanvin Xiao

📖
Aaron Xie
Aaron Xie

📖
nulIptr
nulIptr

📖
Tao Huang
Tao Huang

📖
Yunfly
Yunfly

📖
Will Wang
Will Wang

📖
SyMind
SyMind

📖
yuhengshen
yuhengshen

📖
chenfeng
chenfeng

📖

How to contribute

你可以:

  • 通过 PR 修改错别字,或者错误的格式;
  • 发 issue 讨论文章中出现的一些不合理地方;
  • 翻译 TODO 文件夹下的文章,并顺手 Email 我。

希望你在翻译或者 PR 之前,阅读中文文章排版指北

公众号

最后

如果你和我一样对 TypeScript 充满兴趣,可以订阅(star)本项目,及时收到有关于此项目的更新。

如果你对文章有任何疑问,欢迎提交 issues 和我交流。

如果你认为有些地方翻译不够准确,或者你想补充一些文中没提到但是非常有意思的知识点,欢迎 PR

typescript-book-chinese's People

Contributors

buptsteve avatar byog avatar chenc041 avatar chenwangji avatar daskyrk avatar dependabot[bot] avatar dickeylth avatar duyueyu avatar geekrainy avatar halfakilo avatar helloforrestworld avatar hopalay avatar itxuye avatar jkchao avatar junaya avatar knorienchang avatar lxvc avatar magic-akari avatar profbramble avatar rem486 avatar s1ngs1ng avatar shenzekun avatar vinzid avatar whinc avatar wqcstrong avatar xfields avatar xhwgood avatar xiaobo2020 avatar zhazhengrefn avatar zongzi531 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typescript-book-chinese's Issues

jsx部分内容存在过时和错误

译文:https://jkchao.github.io/typescript-book-chinese/jsx/nonReactJSX.html#jsxfactory

有两个问题:

  1. --jsxFactory 选项 tsc 已废弃(找不到该选项了),建议将该小标题添加废弃标识或说明。
  2. jsx 编译提示编译结果错误(原书也是错的),建议更正并添加说明
/** @jsx jsxFactory */
import { jsxFactory } from 'jsxFactory';

var div = <div>Hello JSX!</div>;

书中结果是:

'use strict';
var jsxFactory_1 = require('jsxFactory');
var div = jsxFactory_1.jsxFactory.createElement('div', null, 'Hello JSX!');

实际结果是(在 Typescript 3.8.3 编译器上运行),没有.createElement

"use strict";
/** @jsx jsxFactory */
var jsxFactory_1 = require("jsxFactory");
var div = jsxFactory_1.jsxFactory("div", null, "Hello JSX!");

重现链接:
Playground Link

用 Decorator 限制函数返回参数的类型

如下代码所示:

const TestDecorator = () => {
  return (
    target: Object,
    key: string | symbol,
    descriptor: TypedPropertyDescriptor<() => number>   // 函数返回值必须是 number
  ) => {
    // ...
  }
}

class Test {
  @TestDecorator()
  testMethod() {
    return '123';   // Error: '123' 是 string 类型
  }
}

错别字“当”

Typescript 类型系统=》泛型=》误用的泛型中

“在这里,泛型完全没有必要使用,因为它仅用于当个参数的位置,使用如下方式可能更好:”

应该是 “单个”

辨析联合类型和引用的问题

正常情况下:

interface Square {
    kind: 'square';
    size: number;
}

interface Rectangle {
    kind: 'rectangle';
    width: number;
    height: number;
}

type Shape = Square | Rectangle;

function size(s: Shape) {
    // 基于 联合类型 和 kind 特殊字面量
    // 如果我们用了判断语句,ts会自动帮我们缩小类型范围
    if (s.kind === 'square') {
        return s.size * s.size
    }
    // 这里ts推断出 s 是 Rectangle
    return s.width * s.height
}

不符合预期的一种情况:

interface Square {
    kind: 'square';
    size: number;
}

interface Rectangle {
    kind: 'rectangle';
    width: number;
    height: number;
}

type Graph = {
    [key: string]: Square | Rectangle
}

function size(s: Graph, key: string) {
    if (s[key].kind === 'square') {
        return s[key].size * s[key].size // Error
    }
    return s[key].width * s[key].height // Error
}

对于不符合逾期的情况有点不解,为什么ts对于这种情况推断不出来呢?

Reflect Metadata demo有错

(这篇文章的demo有问题:https://jkchao.github.io/typescript-book-chinese/tips/metadata.html#%E5%9F%BA%E7%A1%80))。
原文:
譬如在 vue-property-decorator 6.1 及其以下版本中,通过使用 Reflect.getMetadata API,Prop Decorator 能获取属性类型传至 Vue,简要代码如下:

function Prop(): PropertyDecorator { return (target, key: string) => { const type = Reflect.getMetadata('design:type', target, key); console.log(${key} type: ${type.name}`);
// other...
};
}

class SomeClass {
@prop()
public Aprop!: string;
}
`

代码运行有问题。改成如下则没问题:

function Prop(): Function { return (target, key: string) => { const type = Reflect.getMetadata('design:type', target, key); console.log(${key} type: ${type.name}`);
// other...
};
}

class SomeClass {
@prop()
public Aprop!: string;
}
`

Tips 下 Reflect Metadata得章节 Controller 与 Get 的实现 案例有误!缺少函数 isFunction 和 isConstructor

function mapRoute(instance: Object) {
  const prototype = Object.getPrototypeOf(instance);

  // 筛选出类的 methodName
  const methodsNames = Object.getOwnPropertyNames(prototype)
                              .filter(item => !isConstructor(item) && isFunction(prototype[item]))
  return methodsNames.map(methodName => {
    const fn = prototype[methodName];

    // 取出定义的 metadata
    const route = Reflect.getMetadata(PATH_METADATA, fn);
    const method = Reflect.getMetadata(METHOD_METADATA, fn)
    return {
      route,
      method,
      fn,
      methodName
    }
  })
};

这里缺少 isConstructor 和 isFunction函数。

测试之后,加上这俩函数即可解决问题。

export const isFunction = (fn: any): boolean => typeof fn === 'function';
export const isConstructor = (fn: any): boolean => fn === 'constructor';

问一个接口的问题

 interface ObjINF1 {
    [key: string]: string | number | undefined;
}
interface ObjINF2 {
    id: number;
    title: string;
}
function a1(objArr: ObjINF1[]) {
    
}
function a2(objArr: ObjINF2[]) {
// Argument of type 'ObjINF2[]' is not assignable to parameter of type 'ObjINF1[]'.Type 'ObjINF2' is not assignable to type 'ObjINF1'. Index signature is missing in type 'ObjINF2'.
    a1(objArr) 
}

function a3(objArr: {
    id: number;
    title: string;
}[]) {
    a1(objArr) 
}

为什么a2报错了 a3 反而正确

P109 ts-node不需要加引号

没看英文版的,中文版的确有问题
"build:live": "nodemon --watch './src/**/*.ts' --exec 'ts-node' src/index.ts"
运行会报错,需要去掉ts-node的引号可以运行

默认导出语法错误

export default (someVal = 123); 默认导出变量这种写法是不受支持的;
const sumVal: number = 123; export default sumVal; 这样写就是正确的。

文档是基于ts哪个版本编写的呢?

null 和 undefined 这一节

// strictNullChecks: false

let num: number;
let str: string;

// 这些类型能被赋予
num = null;
str = undefined;

这里压根就通过不了

一些有趣的映射类型

tuple to union

type ElementOf<T> = T extends Array<infer E> ? E : T

type ATuple = ['hello', 'world'];

type ToUnion = ElementOf<ATuple>; // 'hello' | 'world'

另一种方法:

type TTuple = [string, number];
type Res = TTuple[number];  // string | number

模块章节默认导入/导出小节内容有误

在该小节给出的例子中有:

// some var
export default (someVar = 123);

在实现中采用这种方法会报错。
建议改为:

export default  123;

// 或

var someVar = 123;
export default someVar;

请问下有pdf吗?

原版说有pdf,结果最近build成功的版本已经是一年前过期的版本了……请问中文版是不是没有pdf呀?

"可调用的" 这一章翻译的太生硬

个人感觉改成"接口定义函数类型" 更合适. 直接翻译不利于理解. 如果不是懂一点函数类型定义, 我估计我怎么也看不懂这一章.

关于类装饰器和元数据的问题

有个疑问请教各位:
这篇文章此处有段代码:

type Constructor<T = any> = new (...args: any[]) => T;

const Injectable = (): ClassDecorator => target => {};

class OtherService {
  a = 1;
}

@Injectable()
class TestService {
  constructor(public readonly otherService: OtherService) {}

  testMethod() {
    console.log(this.otherService.a);
  }
}

const Factory = <T>(target: Constructor<T>): T => {
  // 获取所有注入的服务
  const providers = Reflect.getMetadata('design:paramtypes', target); // [OtherService]
  const args = providers.map((provider: Constructor) => new provider());
  return new target(...args);
};

Factory(TestService).testMethod(); // 1

其中 Injectable 装饰器实质上并没有对 TestService 类进行修改,那为什么这边还要加上这个类装饰器呢?
实验证明,如果不加上的话,Reflect.getMetadata('design:paramtypes', target) 将无效,这是为什么呢?

谢谢解答!

提问一个问题,也请各位大佬帮忙解答一下

使用 react: 15.4.2
架构基于这个版本 封装了一个lib

import {
  LuPage,
} from 'lubase';

lubase并没有以typescript实现

我们现在业务线每个页面继承这个LuPage (它会继承React.Component)

现在我们业务上要接入typescript, 遇到一个问题就是

在继承这个LuPage要设置 props state 类型

interface IProps {
  color: string,
  size?: string,
}

interface IState {
  count: number,
}

class Test extends LuPage<IProps, IProps> {
}

这样设置是无效的,请问下有美誉办法解决这个问题呢

index.d.ts

 declare module 'lubase';

非常感谢!

翻译:literals 及其他

这里有一篇Stack overflow的文章

literals 应该是字面量,
constants 是常量。

翻译里用“文字”明显很令人抓瞎,如:
截屏2020-05-09 16 57 13
原文:
截屏2020-05-09 16 57 27

命名空间的例子

(function(something) {
  something.foo = 123;
})(something || (something = {}));

这段代码如果直接拿来执行,会报错 Uncaught ReferenceError: something is not defined
我也看了原作者的这里,同样是没有对 something 进行声明,不太明白原作者的意图,但是这让代码片段显得不完整也有歧义。

var something
(function(something) {
  something.foo = 123;
})(something || (something = {}));

我想翻看 MDN 中关于这里的一些细节,但是没有找到,就提一个 issues

【PR】 - 调整模块推荐写法文案,避免歧义

首先感谢作者的辛勤付出👏;

其次我在阅读时,发现下面问题:

  • Typescript项目 - 模块章节下

  • 关于推荐的模块写法存在歧义;

怎么书写 TypeScript 模块,这也是一件让人困惑的事。在今天我们应该这么做:

使用 ES 模块语法代替 import foo = require('foo') 即 import/require 语法,
  • 新手可能无法区分ES 模块语法import foo = require('foo')import/require 语法这3个概念的意思

  • 其可能理解为 ES 模块语法import/require 语法是同一个概念,也可能理解为import foo = require('foo')import/require 语法是同一个概念;存在一定的语法歧义;(我让同事阅读了一下,他也认为存在一定歧义😢)

  • 修改成下面的形式,是否更清晰😃:

怎么书写 TypeScript 模块,这也是一件让人困惑的事。在今天我们应该这么做:

放弃使用`import/require`语法即`import foo = require('foo')`写法

推荐使用 ES 模块语法
  • 最后,我创建了一个PR来尝试修复这个问题
    #120

什么是 place

在文件模块详情中的(什么是place)这一段接释的比较模糊,估计是翻译的不是很好,需要看很多遍才能理解

当我提及被检查的 place 时,我想表达的是在这个 place 上,TypeScript 将会检查以下内容(例如一个 foo 的 place):
如果这个 place 表示一个文件,如:foo.ts,欢呼!
否则,如果这个 place 是一个文件夹,并且存在一个文件 foo/index.ts,欢呼!
否则,如果这个 place 是一个文件夹,并且存在一个 foo/package.json 文件,在该文件中指定 types 的文件存在,那么就欢呼!
否则,如果这个 place 是一个文件夹,并且存在一个 package.json 文件,在该文件中指定 main 的文件存在,那么就欢呼!
从文件类型上来说,我实际上是指 .ts, .d.ts 或者 .js

这里的place很明显根本就没有接释其含义,下面就直接开始用这个术语进行表述了,初次看的时候是一头雾水,显然翻译的不够人性化。

infer 介绍这里 例子有错误吧?

`interface User {
name: string;
age: number;
}

type Func = (user: User) => void;

type Param = ParamType; // Param = User
type AA = ParamType; // string
`
Param 应该是 [User]

翻译的太水

How you write TypeScript modules is also a bit of a mess. Again here is how not to do it today:
import foo = require('foo'). i.e. import/require. Use ES module syntax instead.

翻译成了:

怎么书写 TypeScript 模块,这也是一件让人困惑的事。在今天我们应该这么做:
import foo = require('foo') 例如: import/require 使用 ES 模块语法。

各位看看有没有问题

类可以实现接口 是不是写的有点问题

// 工具中提示 缺少分号,看了下官网 好像是要写分号的,刚学也不是很懂
interface IPoint {
x: number, //是不是应该是 ;
y: number
}

class MyPoint implements IPoint {
x: number, //是不是应该是 ;
y: number // Same as Point
}

something || (something = {})

(function(something) {
something.foo = 123;
})(something || (something = {}));

‘something || (something = {})’ 这写法不会报错吗?something都没有声明

全局模块

全局模块不导入导出就能使用?怎么我写的不行

关于 减少 setter 属性的使用

为什么Foo的两个属性a和b,但是却用setBar来对其进行赋值呢,
既然如此为什么Foo类不是

class Foo{
  bar:{a:number,b:number}
}

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.