Skip to content

Commit

Permalink
Add JavaScript Essentials
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingwl committed Feb 22, 2020
1 parent ce15263 commit 6dcdb69
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 144 deletions.
Original file line number Diff line number Diff line change
@@ -1,45 +1,40 @@
//// { order: 3, compiler: { strictNullChecks: true } }

// How code flows inside our JavaScript files can affect
// the types throughout our programs.
// JavaScript 文件中的代码流会影响整个程序的类型。

const users = [{ name: "Ahmed" }, { name: "Gemma" }, { name: "Jon" }];

// We're going to look to see if we can find a user named "jon".
// 我们尝试找到名为 “jon” 的用户。
const jon = users.find(u => u.name === "jon");

// In the above case, 'find' could fail. In that case we
// don't have an object. This creates the type:
// 在上面的情况中,“find” 可能失败,在这种情况下我们不能得到一个对象,
// 它会创建如下类型:
//
// { name: string } | undefined
//
// If you hover your mouse over the three following uses of 'jon' below,
// you'll see how the types change depending on where the word is located:
// 如果您将鼠标悬停在下面的三个用到 ‘jon’ 的地方,您会看到类型的
// 变化依赖于文本在哪里:

if (jon) {
jon;
} else {
jon;
}

// The type '{ name: string } | undefined' uses a TypeScript
// feature called union types. A union type is a way to
// declare that an object could be one of many things.
// 类型 ‘{ name: string } | undefined’ 使用了叫做
// 联合类型的 TypeScript 的功能,联合类型是声明对象可能是
// 几种东西之一的方式。
//
// The pipe acts as the separator between different types.
// JavaScript's dynamic nature means that lots of functions
// receive and return objects of unrelated types and we need
// to be able to express which ones we might be dealing with.
// 管道充当不同类型间的分隔符,JavaScript 的动态特性意味着许多
// 函数会收到和返回不同类型的对象,因此我们需要能够表达需要处理的对象。

// We can use this in a few ways. Let's start by looking at
// an array where the values have different types.
// 我们可以通过几种方式来使用它。让我们看一下具有不同类型的值的数组。

const identifiers = ["Hello", "World", 24, 19];

// We can use the JavaScript 'typeof x === y' syntax to
// check for the type of the first element. You can hover on
// 'randomIdentifier' below to see how it changes between
// different locations
// 我们可以使用 ‘typeof x === y’ 的 JavaScript 语法来检查第一个
// 元素的类型。您可以将鼠标悬停在下面的 ‘randomIdentifier’ 上以
// 查看它在不同的位置之间的变化。

const randomIdentifier = identifiers[0];
if (typeof randomIdentifier === "number") {
Expand All @@ -48,16 +43,14 @@ if (typeof randomIdentifier === "number") {
randomIdentifier;
}

// This control flow analysis means that we can write vanilla
// JavaScript and TypeScript will try to understand how the
// code types will change in different locations.
// 控制流分析代表着我们可以编写原始 JavaScript,而 TypeScript 将尝试
// 去了解代码类型在不同位置如何变化。

// To learn more about code flow analysis:
// 去了解更多关于代码流分析的信息:
// - example:type-guards

// To continue reading through examples you could jump to a
// few different places now:
// 要继续阅读示例,您可以跳转到以下不同的位置:
//
// - Modern JavaScript: example:immutability
// - Type Guards: example:type-guards
// - Functional Programming with JavaScript example:function-chaining
// - 现代 JavaScript: example:immutability
// - 类型守卫: example:type-guards
// - JavaScript 函数式编程 example:function-chaining
Original file line number Diff line number Diff line change
@@ -1,89 +1,73 @@
//// { order: 2, compiler: { noImplicitAny: false } }

// There are quite a few ways to declare a function in
// JavaScript. Let's look at a function which adds two
// numbers together:
// 在 JavaScript 中有很多方式可以声明函数。让我们看一个将两个
// 数字相加的函数:

// Creates a function in global scope called addOldSchool
// 创建一个叫做 addOldSchool 的全局函数。
function addOldSchool(x, y) {
return x + y;
}

// You can move the name of the function to a variable
// name also
const anonymousOldSchoolFunction = function(x, y) {
// 您也可以将函数的名称移动到一个变量名中。
const anonymousOldSchoolFunction = function (x, y) {
return x + y;
};

// You can also use fat-arrow shorthand for a function
// 您也可以使用箭头函数作为函数的快捷方式。
const addFunction = (x, y) => {
return x + y;
};

// We're going to focus on the last one, but everything
// applies to all three formats.
// 我们将着重介绍最后一种方式,但是所有内容都适用于全部三种方式。

// TypeScript provides additional syntax which adds to a
// function definition and offers hints on what types
// are expected by this function.
// TypeScript 提供了函数定义和标记函数预期类型的额外语法。
//
// Up next is the most open version of the add function, it
// says that add takes two inputs of any type: this could
// be strings, numbers or objects which you've made.
// 接下来是 add 函数的最开放的版本,它代表 add 接受任意类型的两个
// 输入:它可以是您输入的字符串,数字或对象。

const add1 = (x: any, y: any) => {
return x + y;
};
add1("Hello", 23);

// This is legitimate JavaScript (strings can be added
// like this for example) but isn't optimal for our function
// which we know is for numbers, so we'll convert the x and
// y to only be numbers.
// 这是合法的 JavaScript(例如可以这样连接字符串),但是对于我们
// 已知的适用于数字的函数并不是最佳选择。因此我们将 x 和 y 转换为
// 仅接受数字。

const add2 = (x: number, y: number) => {
return x + y;
};
add2(16, 23);
add2("Hello", 23);

// Great. We get an error when anything other than a number
// is passed in. If you hover over the word add2 above,
// you'll see that TypeScript describes it as:
// 很好,如果我们传入任何其他非数字的东西可以得到一个错误。如果
// 您将鼠标悬停在上面的 add2 上,您将会看到 TypeScript 将其描述为:
//
// const add2: (x: number, y: number) => number
//
// Where it has inferred that when the two inputs are
// numbers the only possible return type is a number.
// This is great, you don't have to write extra syntax.
// Let's look at what it takes to do that:
// 推断出两个输入都是数字时,数字也是唯一可能的返回值类型。很好,您不
// 需要编写额外的语法。让我们看看这样做的必要条件:

const add3 = (x: number, y: number): string => {
return x + y;
};

// This function fails because we told TypeScript that it
// should expect a string to be returned but the function
// didn't live up to that promise.
// 这个函数将会报错,因为我们告诉 TypeScript 应该返回一个字符串,
// 但是函数没有实现其承诺。

const add4 = (x: number, y: number): number => {
return x + y;
};

// This is a very explicit version of add2 - there are
// cases when you want to use the explicit return type
// syntax to give yourself a space to work within before
// you get started. A bit like how test-driven development
// recommends starting with a failing test, but in this case
// it's with a failing shape of a function instead.
// 这是非常明确的 add2 的版本——在某些情况下,您希望使用显式的返回类型
// 语法给自己在开始前留下一些工作空间。和测试驱动开发建议从失败的测试开始
// 类似。但是在这种情况下,它的函数是不正确的。

// This example is only a primer, you can learn a lot more
// about how functions work in TypeScript in the handbook and
// inside the Functional JavaScript section of the examples:
// 此示例仅是入门知识,您可以在手册以及 JavaScript 函数式编程的示例中
// 了解更多关于 TypeScript 函数的工作原理:
//
// https://www.typescriptlang.org/docs/handbook/functions.html
// example:function-chaining

// And to continue our tour of JavaScript essentials,
// we'll look at how code flow affects the TypeScript types:
// 为了继续学习 JavaScript 精粹,我们将了解代码流如何影响 TypeScript 的类型:
// example:code-flow
Original file line number Diff line number Diff line change
@@ -1,34 +1,28 @@
//// { order: 0, compiler: { target: 1 } }

// Welcome to the TypeScript playground. This site is a lot
// like running a TypeScript project inside a web browser.
// 欢迎来到 TypeScript 在线演示,本网站很像在浏览器中运行
// 一个 TypeScript 项目。

// The playground makes it easy for you to safely experiment
// with ideas in TypeScript by making it trivial to share
// these projects. The URL for this page is everything
// required to load the project for someone else.
// 通过分享这些项目,可以轻松并安全的通过在线演示在 TypeScript 中
// 尝试想法。此页面的 URL 是其他人加载本项目所需的全部内容。

const hello = "Hello"

// You can see on the right the result of the TypeScript
// compiler: this is vanilla JavaScript which can run on
// browsers, servers or anywhere really.
// 你可以在右侧看到 TypeScript 编译器的输出结果:这是可以在浏览器、
// 服务器或任何实际位置上运行的原始 JavaScript。

const world = "World"

// You can see how it makes tiny changes to the code, by
// converting a "const" to a "var". This is one of the many
// things TypeScript does to make it possible to run
// anywhere JavaScript runs.
// 通过将 “const” 改为 “var”,您可以看到它如何对代码进行微小的更高。
// 这是使 TypeScript 为了可以运行在任何运行 JavaScript 的地方所
// 做的工作之一。

console.log(hello + " " + world)

// Now that you have an idea of how the playground works,
// let's look at how TypeScript makes working with
// JavaScript more fun. During this section we'll be trying
// to keep as close to vanilla JavaScript as possible to
// show how you can re-use existing knowledge.
// 现在您已经了解了 TypeScript 的工作原理,让我们了解一下 TypeScript
// 如何使使用 JavaScript 更有趣。在本节中,我们将尽可能接近原生 JavaScript,
// 已显示如何复用现有知识。
//
// Click below to continue:
// 点击下方继续:
//
// example:objects-and-arrays
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
//// { order: 1, compiler: { strict: false } }

// JavaScript objects are collections of values wrapped up
// with named keys.
// JavaScript 对象是用具名键包装的值的集合。

const userAccount = {
name: "Kieron",
id: 0
}

// You can combine these to make larger, more complex
// data-models.
// 您可以将他们合并已获得一个更大更复杂的数据模型。

const pie = {
type: "Apple"
Expand All @@ -20,92 +18,72 @@ const purchaseOrder = {
item: pie
}

// If you use your mouse to hover over some of these words
// (try purchaseOrder above) you can see how TypeScript is
// interpreting your JavaScript into labeled types.
// 如果您将鼠标悬停在这些单词上(尝试上面的 purchaseOrder),您可以
// 看到 TypeScript 是如何将您的 JavaScript 解释为被标记的类型。

// Values can be accessed via the ".", so to get a
// username for a purchase order:
// 值可以通过“.”(点)访问,可以获取一个采购订单的用户名:
console.log(purchaseOrder.item.type)

// If you hover your mouse over each part of the code
// between the ()s, you can see TypeScript offering more
// information about each part. Try re-writing this below:
// 如果您用鼠标悬停在括号之间的代码的每个部分上,您可以看到 TypeScript
// 为每个部分都提供了更多的信息。尝试重写下面的内容:

// Copy this in the next line, character by character:
// 把这个完整复制到下一行:
//
// purchaseOrder.item.type

// TypeScript 向在线演示提供关于此文件中可用的 JavaScript 对象
// 的反馈,让您可以减少输入错误并且可以查看额外的信息,而不必在
// 其他地方查找。

// TypeScript provides feedback to the playground
// about what JavaScript objects are available in this
// file and lets you avoid typoes and see additional
// information without having to look it up in another place.

// TypeScript also offers these same features to arrays.
// Here's an array with just our purchase order above in it.
// TypeScript 对于数组同样提供了相同的功能。这里有一个数组,其中
// 只有一个我们的采购订单。

const allOrders = [purchaseOrder]

// If you hover on allOrders, you can tell it's an array
// because the hover info ends with []. You can access the
// first order by using square brackets with an index
// (starting from zero).
// 如果您将鼠标悬停在 allOrders 上,你可以判断它是一个数组,因为悬停
// 信息以 [] 结尾。您可以使用方括号和索引(从 0 开始)来进行一阶访问。

const firstOrder = allOrders[0]
console.log(firstOrder.item.type)

// An alternative way to get an object is via pop-ing the
// array to remove objects. Doing this removes the object
// from the array, and returns the object. This is called
// mutating the array, because it changes the underlying
// data inside it.
// 获取对象的另一种方式是 pop 数组以删除对象。这样做会从数组中删除对象,
// 并返回被删除的对象。这被称为修改数组,因为它会更改其中的基础数据。

const poppedFirstOrder = allOrders.pop()

// Now allOrders is empty. Mutating data can be useful for
// many things, but one way to reduce the complexity in your
// codebases is to avoid mutation. TypeScript offers a way
// to declare an array readonly instead:
// 现在 allOrders 是空的。修改数据对很多东西都很有用,但是减少修改数据是
// 降低代码复杂度的一种方式。TypeScript 提供了一种声明只读数组的方式:

// Creates a type based on the shape of a purchase order:
// 创建一个基于采购订单的形状创建另一个类型:
type PurchaseOrder = typeof purchaseOrder

// Creates a readonly array of purchase orders
// 创建一个采购订单的只读数组:
const readonlyOrders: readonly PurchaseOrder[] = [purchaseOrder]

// Yep! That's a bit more code for sure. There's four
// new things here:
// 是的!当然还有更多代码,这里有 4 个新事物:
//
// type PurchaseOrder - Declares a new type to TypeScript.
// 类型 PurchaseOrder - TypeScript 声明一个新类型。
//
// typeof - Use the type inference system to set the type
// based on the const which is passed in next.
// typeof - 让类型推断系统基于后面传入的常量推断类型。
//
// purchaseOrder - Get the variable purchaseOrder and tell
// TypeScript this is the shape of all
// objects in the orders array.
// purchaseOrder - 获取 purchaseOrder 变量,并且告诉 TypeScript
// 这是 orders 数组中所有对象的形状。
//
// readonly - This object does not support mutation, once
// it is created then the contents of the array
// will always stay the same.
// readonly - 这个对象不支持被修改,当创建后,数组的内容将始终如一。
//
// Now if you try to pop from the readonlyOrders, TypeScript
// will raise an error.
// 现在如果您尝试 pop readonlyOrders,TypeScript 将会抛出一个错误。

readonlyOrders.pop()

// You can use readonly in all sorts of places, it's a
// little bit of extra syntax here and there, but it
// provides a lot of extra safety.
// 您可以在各种地方使用 readonly,虽然这有一些额外的语法,但是
// 同样会提供很多额外的安全性。

// You can find out more about readonly:
// 您可以找到更多关于 readonly 的信息:
// - [handbook link]
// - https://basarat.gitbooks.io/typescript/content/docs/types/readonly.html

// And you can carry on learning about JavaScript and
// TypeScript in the example on functions:
// 并且您可以在函数的示例中继续了解 JavaScript 和 TypeScript:
// example:functions
//
// Or if you want to know more about immutability:
// 或者您可以了解更多关于不可变性的信息:
// example:immutability

0 comments on commit 6dcdb69

Please sign in to comment.