From fb00d582ccb82f250742b8b80db471884a1ad46b Mon Sep 17 00:00:00 2001
From: hanyujie2002 <84226578+hanyujie2002@users.noreply.github.com>
Date: Sat, 8 Jun 2024 11:56:50 +0800
Subject: [PATCH] init translation of ts for functional programmer
---
.../TS for Functional Programmers.md | 380 ++++++------------
1 file changed, 134 insertions(+), 246 deletions(-)
diff --git a/docs/documentation/zh/get-started/TS for Functional Programmers.md b/docs/documentation/zh/get-started/TS for Functional Programmers.md
index f1ffe1d..ca698b5 100644
--- a/docs/documentation/zh/get-started/TS for Functional Programmers.md
+++ b/docs/documentation/zh/get-started/TS for Functional Programmers.md
@@ -1,65 +1,48 @@
---
-title: TypeScript for Functional Programmers
-short: TS for Functional Programmers
+title: 面向函数式编程者的 TypeScript
+short: 面向函数式编程者的 TypeScript
layout: docs
permalink: /zh/docs/handbook/typescript-in-5-minutes-func.html
-oneline: Learn TypeScript if you have a background in functional programming
+oneline: 如果你有函数式编程背景,就来学习 TypeScript 吧
---
-TypeScript began its life as an attempt to bring traditional object-oriented types
-to JavaScript so that the programmers at Microsoft could bring
-traditional object-oriented programs to the web. As it has developed, TypeScript's type
-system has evolved to model code written by native JavaScripters. The
-resulting system is powerful, interesting and messy.
+TypeScript 最初的目的是为 JavaScript 引入传统的面向对象类型系统,以便微软的程序员能够将传统的面向对象程序带到 web 上。随着其发展,TypeScript 的类型系统已经演化为更好地模拟原生 JavaScript 开发者编写的代码。最终其拥有一个强大、有趣且复杂的体系。
-This introduction is designed for working Haskell or ML programmers
-who want to learn TypeScript. It describes how the type system of
-TypeScript differs from Haskell's type system. It also describes
-unique features of TypeScript's type system that arise from its
-modelling of JavaScript code.
+本介绍面向具有 Haskell 或 ML 编程背景的从业者,旨在介绍 TypeScript 的类型系统如何与 Haskell 的类型系统不同。本介绍还描述了 TypeScript 类型系统中由于模拟 JavaScript 代码而产生的独特特性。
-This introduction does not cover object-oriented programming. In
-practice, object-oriented programs in TypeScript are similar to those
-in other popular languages with OO features.
+本介绍不涉及面向对象编程。在实践中,TypeScript 中的面向对象程序与其他流行语言中的面向对象程序类似。
-## Prerequisites
+## 前提条件
-In this introduction, I assume you know the following:
+在本介绍中,我们假定你已经具备以下知识:
-- How to program in JavaScript, the good parts.
-- Type syntax of a C-descended language.
+- 使用 JavaScript 的核心部分进行编程。
+- C 系列语言的类型语法。
-If you need to learn the good parts of JavaScript, read
-[JavaScript: The Good Parts](https://shop.oreilly.com/product/9780596517748.do).
-You may be able to skip the book if you know how to write programs in
-a call-by-value lexically scoped language with lots of mutability and
-not much else.
-[R4RS Scheme](https://people.csail.mit.edu/jaffer/r4rs.pdf) is a good example.
+如果你需要学习 JavaScript 的核心部分,请阅读[JavaScript 语言精粹](https://shop.oreilly.com/product/9780596517748.do)。如果你知道如何在一个以调用值为基础、词法作用域的语言中编程(这种语言具有大量的可变性而没有太多其他特性),那么你或许可以跳过这本书。[R4RS Scheme](https://people.csail.mit.edu/jaffer/r4rs.pdf) 就是一个很好的例子。
-[The C++ Programming Language](http://www.stroustrup.com/4th.html) is
-a good place to learn about C-style type syntax. Unlike C++,
-TypeScript uses postfix types, like so: `x: string` instead of `string x`.
+要学习 C 风格的类型声明语法,[C++ 编程语言](http://www.stroustrup.com/4th.html)是一个不错的选择。与 C++ 不同,TypeScript 使用后缀类型注解,例如 `x: string`,而不是 `string x`。
-## Concepts not in Haskell
+## Haskell 中不存在的概念
-### Built-in types
+### 内置类型
-JavaScript defines 8 built-in types:
+JavaScript 定义了 8 种内置类型:
-| Type | Explanation |
-| ----------- | ------------------------------------------- |
-| `Number` | a double-precision IEEE 754 floating point. |
-| `String` | an immutable UTF-16 string. |
-| `BigInt` | integers in the arbitrary precision format. |
-| `Boolean` | `true` and `false`. |
-| `Symbol` | a unique value usually used as a key. |
-| `Null` | equivalent to the unit type. |
-| `Undefined` | also equivalent to the unit type. |
-| `Object` | similar to records. |
+| 类型 | 说明 |
+| ----------- | ---------------------------------------- |
+| `Number` | 双精度 IEEE 754 浮点数。 |
+| `String` | 不可变的 UTF-16 字符串。 |
+| `BigInt` | 以任意精度格式表示的整数。 |
+| `Boolean` | `true` 和 `false`。 |
+| `Symbol` | 唯一值,通常用作键。 |
+| `Null` | 相当于单元类型。 |
+| `Undefined` | 也相当于单元类型。 |
+| `Object` | 类似于记录。 |
-[See the MDN page for more detail](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures).
+[请参见 MDN 页面以了解更多详细信息](https://developer.mozilla.org/docs/Web/JavaScript/Data_structures)。
-TypeScript has corresponding primitive types for the built-in types:
+TypeScript 有相应的基本类型来对应这些内置类型:
- `number`
- `string`
@@ -70,111 +53,89 @@ TypeScript has corresponding primitive types for the built-in types:
- `undefined`
- `object`
-#### Other important TypeScript types
+#### TypeScript 的其他重要类型
-| Type | Explanation |
-| -------------- | ------------------------------------------------------------------------------- |
-| `unknown` | the top type. |
-| `never` | the bottom type. |
-| object literal | eg `{ property: Type }` |
-| `void` | for functions with no documented return value |
-| `T[]` | mutable arrays, also written `Array` |
-| `[T, T]` | tuples, which are fixed-length but mutable |
-| `(t: T) => U` | functions |
+| 类型 | 说明 |
+| -------------- | ------------------------------------------------------------------------ |
+| `unknown` | 顶级类型。 |
+| `never` | 底层类型。 |
+| 对象字面量 | 例如 `{ property: Type }` |
+| `void` | 无记录返回值的函数 |
+| `T[]` | 可变数组,也可以写为 `Array` |
+| `[T, T]` | 元组,长度固定但可变 |
+| `(t: T) => U` | 函数 |
-Notes:
+注意:
-1. Function syntax includes parameter names. This is pretty hard to get used to!
+1. 函数语法包括参数名称。这让人很难习惯!
```ts
let fst: (a: any, b: any) => any = (a, b) => a;
- // or more precisely:
+ // 或更精确地:
let fst: (a: T, b: U) => T = (a, b) => a;
```
-2. Object literal type syntax closely mirrors object literal value syntax:
+2. 对象字面量类型语法与对象字面量值语法非常相似:
```ts
let o: { n: number; xs: object[] } = { n: 1, xs: [] };
```
-3. `[T, T]` is a subtype of `T[]`. This is different than Haskell, where tuples are not related to lists.
+3. `[T, T]` 是 `T[]` 的子类型。这不同于 Haskell,在 Haskell 中元组与列表无关。
-#### Boxed types
+#### 装箱类型
-JavaScript has boxed equivalents of primitive types that contain the
-methods that programmers associate with those types. TypeScript
-reflects this with, for example, the difference between the primitive
-type `number` and the boxed type `Number`. The boxed types are rarely
-needed, since their methods return primitives.
+JavaScript 有基本类型的装箱等价物,包含程序员得以与这些类型相关联的方法。TypeScript 也反映了这一点,例如基本类型 `number` 和装箱类型 `Number` 之间的区别。装箱类型很少需要,因为它们的方法会返回基本类型。
```ts
(1).toExponential();
-// equivalent to
+// 等价于
Number.prototype.toExponential.call(1);
```
-Note that calling a method on a numeric literal requires it to be in
-parentheses to aid the parser.
+请注意,要想用数字字面量调用方法,你需要将其括在括号中,以帮助解析器解析。
-### Gradual typing
+### 渐进式类型
-TypeScript uses the type `any` whenever it can't tell what the type of
-an expression should be. Compared to `Dynamic`, calling `any` a type
-is an overstatement. It just turns off the type checker
-wherever it appears. For example, you can push any value into an
-`any[]` without marking the value in any way:
+TypeScript 使用类型 `any` 来表示任何它无法确定表达式类型的地方。与 `Dynamic` 相比,称 `any` 为类型是一种过度陈述。它只是在任何出现的地方关闭了类型检查器。例如,你可以将任何值推入 `any[]` 而不需要以任何方式标记该值:
```ts twoslash
-// with "noImplicitAny": false in tsconfig.json, anys: any[]
+// 在 tsconfig.json 中设置“noImplicitAny: false”,anys: any[]
const anys = [];
anys.push(1);
anys.push("oh no");
anys.push({ anything: "goes" });
```
-And you can use an expression of type `any` anywhere:
+并且你可以在任何地方使用类型为 `any` 的表达式:
```ts
-anys.map(anys[1]); // oh no, "oh no" is not a function
+anys.map(anys[1]); // oh no,“oh no”不是一个函数
```
-`any` is contagious, too — if you initialize a variable with an
-expression of type `any`, the variable has type `any` too.
+`any` 也具有传染性——如果你用一个类型为 `any` 的表达式初始化一个变量,那么该变量也具有类型 `any`。
```ts
-let sepsis = anys[0] + anys[1]; // this could mean anything
+let sepsis = anys[0] + anys[1]; // 这可能意味着任何东西
```
-To get an error when TypeScript produces an `any`, use
-`"noImplicitAny": true`, or `"strict": true` in `tsconfig.json`.
+要在 TypeScript 产生 `any` 时报错,请在 `tsconfig.json` 中设置 `"noImplicitAny": true` 或 `"strict": true`。
-### Structural typing
+### 结构类型
-Structural typing is a familiar concept to most functional
-programmers, although Haskell and most MLs are not
-structurally typed. Its basic form is pretty simple:
+结构类型是大多数函数式编程语言的一个常见概念,尽管 Haskell 和大多数 ML 语言都不是结构类型。它的基本形式非常简单:
```ts
// @strict: false
-let o = { x: "hi", extra: 1 }; // ok
-let o2: { x: string } = o; // ok
+let o = { x: "hi", extra: 1 }; // 可以
+let o2: { x: string } = o; // 可以
```
-Here, the object literal `{ x: "hi", extra: 1 }` has a matching
-literal type `{ x: string, extra: number }`. That
-type is assignable to `{ x: string }` since
-it has all the required properties and those properties have
-assignable types. The extra property doesn't prevent assignment, it
-just makes it a subtype of `{ x: string }`.
+这里,对象字面量 `{ x: "hi", extra: 1 }` 有一个匹配的字面量类型 `{ x: string, extra: number }`。这种类型可以赋值给 `{ x: string }`,因为它包含了所有必需的属性,并且这些属性的类型是可赋值的。额外的属性并不会阻止赋值,它只是使它成为 `{ x: string }` 的子类型。
-Named types just give a name to a type; for assignability purposes
-there's no difference between the type alias `One` and the interface
-type `Two` below. They both have a property `p: string`. (Type aliases
-behave differently from interfaces with respect to recursive
-definitions and type parameters, however.)
+命名类型只是给类型一个名称;从可赋值性角度来说,下面的类型别名 `One` 和接口类型 `Two` 之间没有差异。它们都有属性 `p: string`。(类型别名和接口在递归定义和类型参数方面的行为是不同的。)
```ts twoslash
// @errors: 2322
@@ -191,17 +152,15 @@ let two: Two = x;
two = new Three();
```
-### Unions
+### 联合类型
-In TypeScript, union types are untagged. In other words, they are not
-discriminated unions like `data` in Haskell. However, you can often
-discriminate types in a union using built-in tags or other properties.
+在 TypeScript 中,联合类型是无标签的。换句话说,它们不是像 Haskell 中的 `data` 一样的判别式联合类型。然而,你通常可以使用内置的标签或其他属性来区分联合类型中的类型。
```ts twoslash
function start(
arg: string | string[] | (() => string) | { s: string }
): string {
- // this is super common in JavaScript
+ // 这在 JavaScript 中非常常见
if (typeof arg === "string") {
return commonCase(arg);
} else if (Array.isArray(arg)) {
@@ -213,21 +172,17 @@ function start(
}
function commonCase(s: string): string {
- // finally, just convert a string to another string
+ // 最后,只需将字符串转换为另一个字符串
return s;
}
}
```
-`string`, `Array` and `Function` have built-in type predicates,
-conveniently leaving the object type for the `else` branch. It is
-possible, however, to generate unions that are difficult to
-differentiate at runtime. For new code, it's best to build only
-discriminated unions.
+`string`、`Array` 和 `Function` 都有内置的类型谓词,可以方便地将对象类型留给 `else` 分支。但是,也可能生成难以在运行时区分的联合类型。对于新的代码,最好只构建判别式联合类型。
-The following types have built-in predicates:
+以下类型有内置的谓词:
-| Type | Predicate |
+| 类型 | 谓词 |
| --------- | ---------------------------------- |
| string | `typeof s === "string"` |
| number | `typeof n === "number"` |
@@ -239,57 +194,45 @@ The following types have built-in predicates:
| array | `Array.isArray(a)` |
| object | `typeof o === "object"` |
-Note that functions and arrays are objects at runtime, but have their
-own predicates.
+请注意,函数和数组在运行时也是对象,但有自己的谓词。
-#### Intersections
+#### 交叉类型
-In addition to unions, TypeScript also has intersections:
+除了联合类型,TypeScript 还有交叉类型:
```ts twoslash
type Combined = { a: number } & { b: string };
type Conflicting = { a: number } & { a: string };
```
-`Combined` has two properties, `a` and `b`, just as if they had been
-written as one object literal type. Intersection and union are
-recursive in case of conflicts, so `Conflicting.a: number & string`.
+`Combined` 有两个属性 `a` 和 `b`,就像它们被写在一个对象字面量类型中一样。如果存在冲突,交叉和联合是递归的,所以 `Conflicting.a: number & string`。
-### Unit types
+### 单元类型
-Unit types are subtypes of primitive types that contain exactly one
-primitive value. For example, the string `"foo"` has the type
-`"foo"`. Since JavaScript has no built-in enums, it is common to use a set of
-well-known strings instead. Unions of string literal types allow
-TypeScript to type this pattern:
+单元类型是基本类型的子类型,只包含一个基本值。例如,字符串 `"foo"` 的类型是 `"foo"`。由于 JavaScript 没有内置的枚举,通常使用一组众所周知的字符串代替。字符串字面量类型的联合允许 TypeScript 对此模式进行类型化:
```ts twoslash
declare function pad(s: string, n: number, direction: "left" | "right"): string;
pad("hi", 10, "left");
```
-When needed, the compiler _widens_ — converts to a
-supertype — the unit type to the primitive type, such as `"foo"`
-to `string`. This happens when using mutability, which can hamper some
-uses of mutable variables:
+当需要时,编译器会将单元类型*扩展*(即转换为超类型)到原始类型,例如 `"foo"` 到 `string`。这在使用可变性时会发生,可能会妨碍一些可变变量的使用:
```ts twoslash
// @errors: 2345
declare function pad(s: string, n: number, direction: "left" | "right"): string;
// ---cut---
let s = "right";
-pad("hi", 10, s); // error: 'string' is not assignable to '"left" | "right"'
+pad("hi", 10, s); // 错误: ‘string’不可赋值给‘"left" | "right"’
```
-Here's how the error happens:
+错误发生的原因如下:
- `"right": "right"`
-- `s: string` because `"right"` widens to `string` on assignment to a mutable variable.
-- `string` is not assignable to `"left" | "right"`
+- `s: string` 因为在赋值给可变变量时,`"right"` 会扩展为 `string`。
+- `string` 不可分配给 `"left" | "right"`
-You can work around this with a type annotation for `s`, but that
-in turn prevents assignments to `s` of variables that are not of type
-`"left" | "right"`.
+你可以用类型注解解决这个问题,但这反过来又会阻止将不是 `"left" | "right"` 类型的变量赋值给 `s`。
```ts twoslash
declare function pad(s: string, n: number, direction: "left" | "right"): string;
@@ -298,42 +241,32 @@ let s: "left" | "right" = "right";
pad("hi", 10, s);
```
-## Concepts similar to Haskell
+## Haskell 类似的概念
-### Contextual typing
+### 上下文类型推断
-TypeScript has some obvious places where it can infer types, like
-variable declarations:
+TypeScript 有一些明显可以推断类型的地方,比如变量声明:
```ts twoslash
let s = "I'm a string!";
```
-But it also infers types in a few other places that you may not expect
-if you've worked with other C-syntax languages:
+但它也会在一些你可能没有预料到的地方推断类型,如果你之前使用过其他 C 语法的语言:
```ts twoslash
declare function map(f: (t: T) => U, ts: T[]): U[];
let sns = map((n) => n.toString(), [1, 2, 3]);
```
-Here, `n: number` in this example also, despite the fact that `T` and `U`
-have not been inferred before the call. In fact, after `[1,2,3]` has
-been used to infer `T=number`, the return type of `n => n.toString()`
-is used to infer `U=string`, causing `sns` to have the type
-`string[]`.
+这里,`n: number` 在这个例子中也是这样,尽管 `T` 和 `U` 在调用之前还没有被推断出来。事实上,在 `[1,2,3]` 被用来推断 `T=number` 之后,`n => n.toString()` 的返回类型被用来推断 `U=string`,导致 `sns` 的类型为 `string[]`。
-Note that inference will work in any order, but intellisense will only
-work left-to-right, so TypeScript prefers to declare `map` with the
-array first:
+请注意,推断会以任何顺序工作,但 intellisense 只会从左到右工作,所以 TypeScript 更倾向于将 `map` 声明为数组在前:
```ts twoslash
declare function map(ts: T[], f: (t: T) => U): U[];
```
-Contextual typing also works recursively through object literals, and
-on unit types that would otherwise be inferred as `string` or
-`number`. And it can infer return types from context:
+上下文类型推断还可以递归地在对象字面量中工作,并推断出原本会被推断为 `string` 或 `number` 的单元类型。它还可以通过上下文推断返回类型:
```ts twoslash
declare function run(thunk: (t: T) => void): T;
@@ -342,47 +275,34 @@ let i: { inference: string } = run((o) => {
});
```
-The type of `o` is determined to be `{ inference: string }` because
+`o` 的类型被确定为 `{ inference: string }`,因为:
-1. Declaration initializers are contextually typed by the
- declaration's type: `{ inference: string }`.
-2. The return type of a call uses the contextual type for inferences,
- so the compiler infers that `T={ inference: string }`.
-3. Arrow functions use the contextual type to type their parameters,
- so the compiler gives `o: { inference: string }`.
+1. 声明初始化程序的上下文类型由声明的类型确定:`{ inference: string }`。
+2. 调用的返回类型使用上下文类型进行推断,所以编译器推断 `T={ inference: string }`。
+3. 箭头函数使用上下文类型来类型化它们的参数,所以编译器给出 `o: { inference: string }`。
-And it does so while you are typing, so that after typing `o.`, you
-get completions for the property `inference`, along with any other
-properties you'd have in a real program.
-Altogether, this feature can make TypeScript's inference look a bit
-like a unifying type inference engine, but it is not.
+这一切都是在你键入时进行的,所以在键入 `o.` 之后,你会得到 `inference` 属性的补全,以及任何其他你在真实程序中会有的属性。总的来说,这个特性可以使 TypeScript 的类型推断看起来有点像一个统一的类型推断引擎,但它并不是这样。
-### Type aliases
+### 类型别名
-Type aliases are mere aliases, just like `type` in Haskell. The
-compiler will attempt to use the alias name wherever it was used in
-the source code, but does not always succeed.
+类型别名只是一个别名,就像 Haskell 中的 `type`。编译器会尝试在源代码中使用别名名称,但并不总是成功。
```ts twoslash
type Size = [number, number];
let x: Size = [101.1, 999.9];
```
-The closest equivalent to `newtype` is a _tagged intersection_:
+最接近 `newtype` 的是 _tagged 交集_:
```ts
type FString = string & { __compileTimeOnly: any };
```
-An `FString` is just like a normal string, except that the compiler
-thinks it has a property named `__compileTimeOnly` that doesn't
-actually exist. This means that `FString` can still be assigned to
-`string`, but not the other way round.
+`FString` 就像一个普通的字符串,只是编译器认为它有一个名为 `__compileTimeOnly` 的属性,实际上并不存在。这意味着 `FString` 仍然可以被赋值给 `string`,但反过来却不行。
-### Discriminated Unions
+### 辨别联合类型
-The closest equivalent to `data` is a union of types with discriminant
-properties, normally called discriminated unions in TypeScript:
+最接近 `data` 的是带有辨别属性的类型联合,通常称为 TypeScript 中的辨别联合:
```ts
type Shape =
@@ -391,11 +311,7 @@ type Shape =
| { kind: "triangle"; x: number; y: number };
```
-Unlike Haskell, the tag, or discriminant, is just a property in each
-object type. Each variant has an identical property with a different
-unit type. This is still a normal union type; the leading `|` is
-an optional part of the union type syntax. You can discriminate the
-members of the union using normal JavaScript code:
+与 Haskell 不同,标签或辨别符只是每个对象类型中的一个属性。每个变体都有一个相同的属性,但单元类型不同。这仍然是一个普通的联合类型;前面的 `|` 是联合类型语法中的可选部分。你可以使用普通的 JavaScript 代码来区分联合的成员:
```ts twoslash
type Shape =
@@ -414,12 +330,9 @@ function area(s: Shape) {
}
```
-Note that the return type of `area` is inferred to be `number` because
-TypeScript knows the function is total. If some variant is not
-covered, the return type of `area` will be `number | undefined` instead.
+请注意,`area` 的返回类型被推断为 `number`,因为 TypeScript 知道该函数是完整的。如果没有涵盖某个变体,`area` 的返回类型将是 `number | undefined`。
-Also, unlike Haskell, common properties show up in any union, so you
-can usefully discriminate multiple members of the union:
+另外,与 Haskell 不同,公共属性出现在任何联合中,所以你可以有效区分联合的多个成员:
```ts twoslash
type Shape =
@@ -437,10 +350,9 @@ function height(s: Shape) {
}
```
-### Type Parameters
+### 类型参数
-Like most C-descended languages, TypeScript requires declaration of
-type parameters:
+与大多数 C 系语言一样,TypeScript 需要声明类型参数:
```ts
function liftArray(t: T): Array {
@@ -448,9 +360,7 @@ function liftArray(t: T): Array {
}
```
-There is no case requirement, but type parameters are conventionally
-single uppercase letters. Type parameters can also be constrained to a
-type, which behaves a bit like type class constraints:
+这里没有大小写要求,但是类型参数通常使用单个大写字母。类型参数也可以被限制为某种类型,这有点像类型类约束:
```ts
function firstish(t1: T, t2: T): T {
@@ -458,14 +368,9 @@ function firstish(t1: T, t2: T): T {
}
```
-TypeScript can usually infer type arguments from a call based on the
-type of the arguments, so type arguments are usually not needed.
+TypeScript 通常可以根据参数的类型推断出类型参数,所以通常不需要指定类型参数。
-Because TypeScript is structural, it doesn't need type parameters as
-much as nominal systems. Specifically, they are not needed to make a
-function polymorphic. Type parameters should only be used to
-_propagate_ type information, such as constraining parameters to be
-the same type:
+由于 TypeScript 是结构化的,它不像名义系统那样需要大量使用类型参数。具体来说,不需要使用类型参数来使一个函数具有多态性。类型参数应该只用于*传播*类型信息,比如限制参数必须是相同的类型:
```ts
function length>(t: T): number {}
@@ -473,31 +378,23 @@ function length>(t: T): number {}
function length(t: ArrayLike): number {}
```
-In the first `length`, T is not necessary; notice that it's only
-referenced once, so it's not being used to constrain the type of the
-return value or other parameters.
+在第一个 `length` 中,T 是不必要的;请注意,它只被引用了一次,所以它不用于限制返回值或其他参数的类型。
-#### Higher-kinded types
+#### 高阶类型
-TypeScript does not have higher kinded types, so the following is not legal:
+TypeScript 没有高阶类型,所以以下代码是无效的:
```ts
function length, U>(m: T) {}
```
-#### Point-free programming
+#### 无点编程
-Point-free programming — heavy use of currying and function
-composition — is possible in JavaScript, but can be verbose.
-In TypeScript, type inference often fails for point-free programs, so
-you'll end up specifying type parameters instead of value parameters. The
-result is so verbose that it's usually better to avoid point-free
-programming.
+在 JavaScript 中,无点编程(大量使用柯里化和函数组合)是可行的,但可能会很冗长。在 TypeScript 中,无点编程的类型推断往往会失败,所以最终你虽然不需要指定值参数,但需要指定类型参数。结果太冗长了,所以通常最好避免使用无点编程。
-### Module system
+### 模块系统
-JavaScript's modern module syntax is a bit like Haskell's, except that
-any file with `import` or `export` is implicitly a module:
+JavaScript 的现代模块语法有点类似 Haskell,只不过任何包含 `import` 或 `export` 的文件都是一个模块:
```ts
import { value, Type } from "npm-package";
@@ -505,14 +402,13 @@ import { other, Types } from "./local-package";
import * as prefix from "../lib/third-package";
```
-You can also import commonjs modules — modules written using node.js'
-module system:
+你也可以导入 CommonJS 模块(使用 Node.js 模块系统编写的模块):
```ts
import f = require("single-function-package");
```
-You can export with an export list:
+你可以使用导出列表导出:
```ts
export { f };
@@ -520,24 +416,21 @@ export { f };
function f() {
return g();
}
-function g() {} // g is not exported
+function g() {} // g 没有被导出
```
-Or by marking each export individually:
+或者将每个导出单独标记:
```ts
export function f() { return g() }
function g() { }
```
-The latter style is more common but both are allowed, even in the same
-file.
+后一种方式更常见,但两种方式都可行的,甚至在单个文件中可以同时使用。
-### `readonly` and `const`
+### `readonly` 和 `const`
-In JavaScript, mutability is the default, although it allows variable
-declarations with `const` to declare that the _reference_ is
-immutable. The referent is still mutable:
+在 JavaScript 中,可变性是默认的,尽管它允许使用 `const` 进行变量声明(其声明*引用*是不可变的),但引用的内容仍然是可变的:
```js
const a = [1, 2, 3];
@@ -545,53 +438,48 @@ a.push(102); // ):
a[0] = 101; // D:
```
-TypeScript additionally has a `readonly` modifier for properties.
+TypeScript 还有一个 `readonly` 修饰符用来修饰属性。
```ts
interface Rx {
readonly x: number;
}
let rx: Rx = { x: 1 };
-rx.x = 12; // error
+rx.x = 12; // 错误
```
-It also ships with a mapped type `Readonly` that makes
-all properties `readonly`:
+它还附带映射类型 `Readonly`,可以将所有属性设置为 `readonly`:
```ts
interface X {
x: number;
}
let rx: Readonly = { x: 1 };
-rx.x = 12; // error
+rx.x = 12; // 错误
```
-And it has a specific `ReadonlyArray` type that removes
-side-affecting methods and prevents writing to indices of the array,
-as well as special syntax for this type:
+它还有一个特定的 `ReadonlyArray` 类型,可以移除有副作用的方法,并防止写入数组索引,同时这种类型的特殊的语法也会移除:
```ts
let a: ReadonlyArray = [1, 2, 3];
let b: readonly number[] = [1, 2, 3];
-a.push(102); // error
-b[0] = 101; // error
+a.push(102); // 错误
+b[0] = 101; // 错误
```
-You can also use a const-assertion, which operates on arrays and
-object literals:
+你也可以使用 const 断言,它可以作用于数组和对象字面量:
```ts
let a = [1, 2, 3] as const;
-a.push(102); // error
-a[0] = 101; // error
+a.push(102); // 错误
+a[0] = 101; // 错误
```
-However, none of these options are the default, so they are not
-consistently used in TypeScript code.
+但是,这些选项都不是默认的,所以在 TypeScript 代码中并不总是一致地使用。
-### Next Steps
+### 下一步
-This doc is a high level overview of the syntax and types you would use in everyday code. From here you should:
+本文档是日常代码中使用的语法和类型的概述。之后你应该:
-- Read the full Handbook [from start to finish](/zh/docs/handbook/intro.html)
-- Explore the [Playground examples](/play#show-examples)
+- [从头到尾](/zh/docs/handbook/intro.html)阅读完整的手册
+- 探索[演练场的示例](/play#show-examples)