Skip to content

Commit

Permalink
Add part of Functions with JavaScript
Browse files Browse the repository at this point in the history
  • Loading branch information
Kingwl committed Feb 22, 2020
1 parent 6dcdb69 commit 900fb3b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
//// { order: 2, compiler: { esModuleInterop: true } }

// Function chaining APIs are a common pattern in
// JavaScript, which can make your code focused
// with less intermediary values and easier to read
// because of their nesting qualities.
// 在 JavaScript 中,链式函数是很常见的 API 模式。由于他们
// 具有嵌套特性,所以可以让您的代码减少中间值,并且增加可读性。

// A really common API which works via chaining
// is jQuery. Here is an example of jQuery
// being used with the types from DefinitelyTyped:
// jQuery 是一个非常常见的可以通过链式使用的 API,这是
// jQuery 与 DefinitelyTyped 中的类型一起使用的示例:

import $ from "jquery";

// Here's an example use of the jQuery API:
// 这是使用 jQuery API 的示例:

$("#navigation")
.css("background", "red")
.height(300)
.fadeIn(200);

// If you add a dot on the line above, you'll see
// a long list of functions. This pattern is easy to
// reproduce in JavaScript. The key is to make sure
// you always return the same object.
// 如果您在上面的行中增加了一个点(.),则会看到一长串函数。
// 这种模式很容易在 JavaScript 中复现。关键是要确保
// 返回相同的对象。

// Here is an example API which creates a chaining
// API. The key is to have an outer function which
// keeps track of internal state, and an object which
// exposes the API that is always returned.
// 这是创建 链式 API 的一个示例。关键是要有一个跟踪内部状态的
// 外部函数,以及一个最终返回的暴露 API 的对象。

const addTwoNumbers = (start = 1) => {
let n = start;

const api = {
// Implement each function in your API
// 实现您 API 中的所有函数
add(inc: number = 1) {
n += inc;
return api;
Expand All @@ -46,16 +40,15 @@ const addTwoNumbers = (start = 1) => {
return api;
};

// Which allows the same style of API as we
// saw in jQuery:
// 允许我们使用与 jQuery 中相同的 API 风格:

addTwoNumbers(1)
.add(3)
.add()
.print()
.add(1);

// Here's a similar example which uses a class:
// 这是一个类似的使用类的示例:

class AddNumbers {
private n: number;
Expand All @@ -75,18 +68,17 @@ class AddNumbers {
}
}

// Here it is in action:
// 它在正常工作:

new AddNumbers(2)
.add(3)
.add()
.print()
.add(1);

// This example used the TypeScript
// type inference to provide a way to
// provide tooling to JavaScript patterns.
// 例子是使用 TypeScript 的类型推导来为 JavaScript 的模式
// 提供帮助的一种方法。

// For more examples on this:
// 更多的例子可以查看:
//
// - example:code-flow
Original file line number Diff line number Diff line change
@@ -1,66 +1,51 @@
// Generics provide a way to use Types as variables in other
// types. Meta.
// 泛型提供了在类型中以变量的形式使用类型的元方法,

// We'll be trying to keep this example light, you can do
// a lot with generics and it's likely you will see some very
// complicated code using generics at some point - but that
// does not mean that generics are complicated.
// 我们将努力使本例保持简洁,您可以使用泛型做很多事,并且您可能有时
// 会看到一些非常复杂的使用泛型的代码——但这并不意味着泛型很复杂。

// Let's start with an example where we wrap an input object
// in an array. We will only care about one variable in this
// case, the type which was passed in:
// 让我们从将 input 对象包装在数组中的示例开始,在这种情况下,我们
// 只关心一个类型变量,即传入的类型。

function wrapInArray<Type>(input: Type): Type[] {
return [input];
}

// Note: it's common to see Type referred to as T. This is
// culturally similar to how people use i in a for loop to
// represent index. T normally represents Type, so we'll
// be using the full name for clarity.
// 注:通常将 Type 称为 T,在文化上,这是一种类似于人们在 for 循环中使用
// i 来表示索引。T 通常表示 Type,因此为了清楚起见,我们将使用全名。

// Our function will use inference to always keep the type
// passed in the same as the type passed out (though
// it will be wrapped in an array).
// 我们的函数将使用推导来确保传入的类型与传出的类型相同(即使它被包含在数组中)。

const stringArray = wrapInArray("hello generics");
const numberArray = wrapInArray(123);

// We can verify this works as expected by checking
// if we can assign a string array to a function which
// should be an object array:
// 我们可以通过检查是否可以将字符串数组赋值诶应为对象数组的函数
// 来验证其是否正常工作。
const notStringArray: string[] = wrapInArray({});

// You can also skip the generic inference by adding the
// type yourself also:
// 您还可以通过自行添加类型来跳过泛型类型推导:
const stringArray2 = wrapInArray<string>("");

// wrapInArray allows any type to be used, however there
// are cases when you need to only allow a subset of types.
// In these cases you can say the type has to extend a
// particular type.
// wrapInArray 允许使用任何类型,但在某些情况下,您只允许某些类型的
// 子集。在这种情况下,您可以指定类型必须扩展特定类型。

interface Drawable {
draw: () => void;
}

// This function takes a set of objects which have a function
// for drawing to the screen
// 这个函数接收一组对象,这些对象具有用于在屏幕上绘制的功能:
function renderToScreen<Type extends Drawable>(input: Type[]) {
input.forEach(i => i.draw());
}

const objectsWithDraw = [{ draw: () => {} }, { draw: () => {} }];
const objectsWithDraw = [{ draw: () => { } }, { draw: () => { } }];
renderToScreen(objectsWithDraw);

// It will fail if draw is missing:
// 如果没有 draw,它会报错:

renderToScreen([{}, { draw: () => {} }]);
renderToScreen([{}, { draw: () => { } }]);

// Generics can start to look complicated when you have
// multiple variables. Here is an example of a caching
// function that lets you have different sets of input types
// and caches.
// 当您有多个变量时,泛型看起来可能会很复杂。这是一个缓存函数的示例,
// 可以让您拥有不同的输入类型和缓存。

interface CacheHost {
save: (a: any) => void;
Expand All @@ -71,29 +56,25 @@ function addObjectToCache<Type, Cache extends CacheHost>(obj: Type, cache: Cache
return cache;
}

// This is the same as above, but with an extra parameter.
// Note: to make this work though, we had to use an any. This
// can be worked out by using a generic interface.
// 这和上面相同,但有一个额外的参数。
// 注:尽管如此,我们必须使用 any。这可以使用泛型接口来解决。

interface CacheHostGeneric<ContentType> {
save: (a: ContentType) => void;
}

// Now when the CacheHostGeneric is used, you need to tell
// it what ContentType is.
// 在使用 CacheHostGeneric 时,您必须告诉它 ContentType 是什么。

function addTypedObjectToCache<Type, Cache extends CacheHostGeneric<Type>>(obj: Type, cache: Cache): Cache {
cache.save(obj);
return cache;
}

// That escalated pretty quickly in terms of syntax. However,
// this provides more safety. These are trade-offs, that you
// have more knowledge to make now. When providing APIs for
// others, generics offer a flexible way to let others use
// their own types with full code inference.
// 单从语法而言,这很快就变复杂了。但是这提供了额外的安全性。这是取舍,您
// 现在有更多相关的知识要做。在为其他人提供 API 时,泛型提供了一种灵活的
// 方法,让他们通过完整的类型推导使用自己的类型。

// For more examples of generics with classes and interfaces:
// 更多关于泛型、类和函数的示例可以查看:
//
// example:advanced-classes
// example:typescript-with-react
Expand Down

0 comments on commit 900fb3b

Please sign in to comment.