Giter VIP home page Giter VIP logo

typescript-book-chinese's Issues

错别字“当”

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

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

应该是 “单个”

默认导出语法错误

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

P109 ts-node不需要加引号

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

something || (something = {})

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

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

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

null 和 undefined 这一节

// strictNullChecks: false

let num: number;
let str: string;

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

这里压根就通过不了

命名空间的例子

(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

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';

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

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

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

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

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

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;
}
`

【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

全局模块

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

问一个接口的问题

 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 反而正确

翻译:literals 及其他

这里有一篇Stack overflow的文章

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

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

关于 减少 setter 属性的使用

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

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

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

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

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

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

export default  123;

// 或

var someVar = 123;
export default someVar;

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

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

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

正常情况下:

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对于这种情况推断不出来呢?

翻译的太水

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 模块语法。

各位看看有没有问题

请问下有pdf吗?

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

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

使用 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';

非常感谢!

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

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

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) 将无效,这是为什么呢?

谢谢解答!

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

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

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

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

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

如下代码所示:

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

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

一些有趣的映射类型

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

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.