jkchao / typescript-book-chinese Goto Github PK
View Code? Open in Web Editor NEWTypeScript Deep Dive 中文版
Home Page: https://jkchao.github.io/typescript-book-chinese/
License: MIT License
TypeScript Deep Dive 中文版
Home Page: https://jkchao.github.io/typescript-book-chinese/
License: MIT License
Typescript 类型系统=》泛型=》误用的泛型中
“在这里,泛型完全没有必要使用,因为它仅用于当个参数的位置,使用如下方式可能更好:”
应该是 “单个”
在TypeScript 类型系统-概览-元组类型章节,文章写到“元组可以包含任意数量的成员”,实际上元组只能包含固定数量的成员。例如:
const a:[string,number] = ["1",2,3];
// error:不能将类型“[string, number, number]”分配给类型“[string, number]”。源具有 3 个元素,但目标仅允许 2 个。
export default (someVal = 123); 默认导出变量这种写法是不受支持的;
const sumVal: number = 123; export default sumVal; 这样写就是正确的。
概览中的内联类型注释的代码示例用错了代码,当前用的是接口的示例代码,应该是内联类型注解的代码
没看英文版的,中文版的确有问题
"build:live": "nodemon --watch './src/**/*.ts' --exec 'ts-node' src/index.ts"
运行会报错,需要去掉ts-node的引号可以运行
(function(something) {
something.foo = 123;
})(something || (something = {}));
‘something || (something = {})’ 这写法不会报错吗?something都没有声明
// strictNullChecks: false
let num: number;
let str: string;
// 这些类型能被赋予
num = null;
str = undefined;
这里压根就通过不了
首先给作者点个赞,还是很棒的,希望有个结合小程序的demo
(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
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';
译文:https://jkchao.github.io/typescript-book-chinese/jsx/nonReactJSX.html#jsxfactory
有两个问题:
--jsxFactory
选项 tsc 已废弃(找不到该选项了),建议将该小标题添加废弃标识或说明。/** @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
const foo = 123
const bar: typeof foo = 456
bar 的类型为123
`interface User {
name: string;
age: number;
}
type Func = (user: User) => void;
type Param = ParamType; // Param = User
type AA = ParamType; // string
`
Param 应该是 [User]
(这篇文章的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;
}
`
下面这一行,“bar”,应该是“Bar”
// 这个块中,一定是 'bar'
这句会报错了, e没有 x属性
首先感谢作者的辛勤付出👏;
其次我在阅读时,发现下面问题:
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 模块语法
原文里是 var,翻译过来是 const ?
翻译: modules.md
原文: modules.md
全局模块不导入导出就能使用?怎么我写的不行
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 反而正确
为什么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;
hi! i maintain https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/
we used to have a chinese version but it fell out of date :)
anyone want to collaborate or maintain chinese version?
个人感觉改成"接口定义函数类型" 更合适. 直接翻译不利于理解. 如果不是懂一点函数类型定义, 我估计我怎么也看不懂这一章.
正常情况下:
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对于这种情况推断不出来呢?
文字【希望你在翻译或者 PR 之前,阅读中文文章排版指北】最后一个字是 【南】吧
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,结果最近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';
非常感谢!
你好,我有在阅读你翻译的书;
我想问下,你这个静态网站
https://jkchao.github.io/typescript-book-chinese/
是如何生成的?
有关键字吗?因为我最近也想弄一个类似的翻译项目!
开篇第一部分中,最后有一句“于是在某天的某个冲动之下,这个 RP 就诞生了”,其中”RP“是指什么?
是否是笔误,应该是”PR“?
有个疑问请教各位:
在这篇文章此处有段代码:
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 上,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
}
如下代码所示:
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
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.