Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #848 from rizalwildan/contents-table
Browse files Browse the repository at this point in the history
Add table of contents pages jsx, mixins, namespace
  • Loading branch information
RyanCavanaugh committed Feb 14, 2019
2 parents 9ccbc76 + 658d76b commit e3f69fe
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
32 changes: 32 additions & 0 deletions pages/JSX.md
@@ -1,11 +1,31 @@
# Table of contents

[Introduction](#introduction)
[Basic Usage](#basic-usage)
[The as operator](#the-as-operator)
[Type Checking](#type-checking)
* [Intrinsic elements](#intrinsic-elements)
* [Value-based elements](#value-based-elements)
* [Stateless Functional Component](#stateless-functional-component)
* [Class Component](#class-component)
* [Attribute type checking](#attribute-type-checking)
* [Children Type Checking](#children-type-checking)

[The JSX result type](#the-jsx-result-type)
[Embedding Expressions](#embedding-expressions)
[React integration](#react-integration)
[Factory Functions](#factory-functions)

# Introduction
<b><a href="#table-of-contents">↥ back to top</a></b>

[JSX](https://facebook.github.io/jsx/) is an embeddable XML-like syntax.
It is meant to be transformed into valid JavaScript, though the semantics of that transformation are implementation-specific.
JSX rose to popularity with the [React](https://reactjs.org/) framework, but has since seen other implementations as well.
TypeScript supports embedding, type checking, and compiling JSX directly to JavaScript.

# Basic usage
<b><a href="#table-of-contents">↥ back to top</a></b>

In order to use JSX you must do two things.

Expand All @@ -30,6 +50,7 @@ You can specify this mode using either the `--jsx` command line flag or the corr
> *Note: The identifier `React` is hard-coded, so you must make React available with an uppercase R.*
# The `as` operator
<b><a href="#table-of-contents">↥ back to top</a></b>

Recall how to write a type assertion:

Expand All @@ -50,6 +71,7 @@ var foo = bar as foo;
The `as` operator is available in both `.ts` and `.tsx` files, and is identical in behavior to the angle-bracket type assertion style.

# Type Checking
<b><a href="#table-of-contents">↥ back to top</a></b>

In order to understand type checking with JSX, you must first understand the difference between intrinsic elements and value-based elements.
Given a JSX expression `<expr />`, `expr` may either refer to something intrinsic to the environment (e.g. a `div` or `span` in a DOM environment) or to a custom component that you've created.
Expand All @@ -63,6 +85,7 @@ TypeScript uses the [same convention that React does](http://facebook.github.io/
An intrinsic element always begins with a lowercase letter, and a value-based element always begins with an uppercase letter.

## Intrinsic elements
<b><a href="#table-of-contents">↥ back to top</a></b>

Intrinsic elements are looked up on the special interface `JSX.IntrinsicElements`.
By default, if this interface is not specified, then anything goes and intrinsic elements will not be type checked.
Expand Down Expand Up @@ -92,6 +115,7 @@ In the above example, `<foo />` will work fine but `<bar />` will result in an e
>```
## Value-based elements
<b><a href="#table-of-contents">↥ back to top</a></b>

Value based elements are simply looked up by identifiers that are in scope.

Expand All @@ -110,6 +134,7 @@ There are two ways to define a value-based element:
Because these two types of value-based elements are indistinguishable from each other in a JSX expression, first TS tries to resolve the expression as Stateless Functional Component using overload resolution. If the process succeeds, then TS finishes resolving the expression to its declaration. If the value fails to resolve as SFC, TS will then try to resolve it as a class component. If that fails, TS will report an error.

### Stateless Functional Component
<b><a href="#table-of-contents">↥ back to top</a></b>

As the name suggests, the component is defined as a JavaScript function where its first argument is a `props` object.
TS enforces that its return type must be assignable to `JSX.Element`.
Expand Down Expand Up @@ -151,6 +176,7 @@ function MainButton(prop: SideProps): JSX.Element {
```

### Class Component
<b><a href="#table-of-contents">↥ back to top</a></b>

It is possible to define the type of a class component.
However, to do so it is best to understand two new terms: the *element class type* and the *element instance type*.
Expand Down Expand Up @@ -217,6 +243,7 @@ function NotAValidFactoryFunction() {
```

## Attribute type checking
<b><a href="#table-of-contents">↥ back to top</a></b>

The first step to type checking attributes is to determine the *element attributes type*.
This is slightly different between intrinsic and value-based elements.
Expand Down Expand Up @@ -292,6 +319,7 @@ var badProps = {};
```

## Children Type Checking
<b><a href="#table-of-contents">↥ back to top</a></b>

In TypeScript 2.3, TS introduced type checking of *children*. *children* is a special property in an *element attributes type* where child *JSXExpression*s are taken to be inserted into the attributes.
Similar to how TS uses `JSX.ElementAttributesProperty` to determine the name of *props*, TS uses `JSX.ElementChildrenAttribute` to determine the name of *children* within those props.
Expand Down Expand Up @@ -359,13 +387,15 @@ class Component extends React.Component<PropsType, {}> {
```

# The JSX result type
<b><a href="#table-of-contents">↥ back to top</a></b>

By default the result of a JSX expression is typed as `any`.
You can customize the type by specifying the `JSX.Element` interface.
However, it is not possible to retrieve type information about the element, attributes or children of the JSX from this interface.
It is a black box.

# Embedding Expressions
<b><a href="#table-of-contents">↥ back to top</a></b>

JSX allows you to embed expressions between tags by surrounding the expressions with curly braces (`{ }`).

Expand All @@ -385,6 +415,7 @@ var a = <div>
```

# React integration
<b><a href="#table-of-contents">↥ back to top</a></b>

To use JSX with React you should use the [React typings](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react).
These typings define the `JSX` namespace appropriately for use with React.
Expand All @@ -407,6 +438,7 @@ class MyComponent extends React.Component<Props, {}> {
```

# Factory Functions
<b><a href="#table-of-contents">↥ back to top</a></b>

The exact factory function used by the `jsx: react` compiler option is configurable. It may be set using either the `jsxFactory` command line option, or an inline `@jsx` comment pragma to set it on a per-file basis. For example, if you set `jsxFactory` to `createElement`, `<div />` will emit as `createElement("div")` instead of `React.createElement("div")`.

Expand Down
9 changes: 9 additions & 0 deletions pages/Mixins.md
@@ -1,9 +1,17 @@
# Table of contents

[Introduction](#introduction)
[Mixin sample](#mixin-sample)
[Understanding the sample](#understanding-the-sample)

# Introduction
<b><a href="#table-of-contents">↥ back to top</a></b>

Along with traditional OO hierarchies, another popular way of building up classes from reusable components is to build them by combining simpler partial classes.
You may be familiar with the idea of mixins or traits for languages like Scala, and the pattern has also reached some popularity in the JavaScript community.

# Mixin sample
<b><a href="#table-of-contents">↥ back to top</a></b>

In the code below, we show how you can model mixins in TypeScript.
After the code, we'll break down how it works.
Expand Down Expand Up @@ -65,6 +73,7 @@ function applyMixins(derivedCtor: any, baseCtors: any[]) {
```

# Understanding the sample
<b><a href="#table-of-contents">↥ back to top</a></b>

The code sample starts with the two classes that will act as our mixins.
You can see each one is focused on a particular activity or capability.
Expand Down
26 changes: 26 additions & 0 deletions pages/Namespaces.md
@@ -1,21 +1,40 @@
# Table of contents

[Introduction](#introduction)
[First steps](#first-steps)
* [Validators in a single file](#validators-in-a-single-file)

[Namespacing](#namespacing)
* [Namespaced Validators](#namespaced-validators)

[Splitting Across Files](#splitting-across-files)
* [Multi-file namespaces](#multi-file-namespaces)

[Aliases](#aliases)
[Working with Other JavaScript Libraries](#working-with-other-javascript-libraries)
* [Ambient Namespaces](#ambient-namespaces)

> **A note about terminology:**
It's important to note that in TypeScript 1.5, the nomenclature has changed.
"Internal modules" are now "namespaces".
"External modules" are now simply "modules", as to align with [ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/)'s terminology, (namely that `module X {` is equivalent to the now-preferred `namespace X {`).

# Introduction
<b><a href="#table-of-contents">↥ back to top</a></b>

This post outlines the various ways to organize your code using namespaces (previously "internal modules") in TypeScript.
As we alluded in our note about terminology, "internal modules" are now referred to as "namespaces".
Additionally, anywhere the `module` keyword was used when declaring an internal module, the `namespace` keyword can and should be used instead.
This avoids confusing new users by overloading them with similarly named terms.

# First steps
<b><a href="#table-of-contents">↥ back to top</a></b>

Let's start with the program we'll be using as our example throughout this page.
We've written a small set of simplistic string validators, as you might write to check a user's input on a form in a webpage or check the format of an externally-provided data file.

## Validators in a single file
<b><a href="#table-of-contents">↥ back to top</a></b>

```ts
interface StringValidator {
Expand Down Expand Up @@ -55,6 +74,7 @@ for (let s of strings) {
```

# Namespacing
<b><a href="#table-of-contents">↥ back to top</a></b>

As we add more validators, we're going to want to have some kind of organization scheme so that we can keep track of our types and not worry about name collisions with other objects.
Instead of putting lots of different names into the global namespace, let's wrap up our objects into a namespace.
Expand All @@ -65,6 +85,7 @@ Conversely, the variables `lettersRegexp` and `numberRegexp` are implementation
In the test code at the bottom of the file, we now need to qualify the names of the types when used outside the namespace, e.g. `Validation.LettersOnlyValidator`.

## Namespaced Validators
<b><a href="#table-of-contents">↥ back to top</a></b>

```ts
namespace Validation {
Expand Down Expand Up @@ -105,10 +126,12 @@ for (let s of strings) {
```

# Splitting Across Files
<b><a href="#table-of-contents">↥ back to top</a></b>

As our application grows, we'll want to split the code across multiple files to make it easier to maintain.

## Multi-file namespaces
<b><a href="#table-of-contents">↥ back to top</a></b>

Here, we'll split our `Validation` namespace across many files.
Even though the files are separate, they can each contribute to the same namespace and can be consumed as if they were all defined in one place.
Expand Down Expand Up @@ -204,6 +227,7 @@ If multiple JS files get produced, we'll need to use `<script>` tags on our webp
```
# Aliases
<b><a href="#table-of-contents">↥ back to top</a></b>
Another way that you can simplify working with namespaces is to use `import q = x.y.z` to create shorter names for commonly-used objects.
Not to be confused with the `import x = require("name")` syntax used to load modules, this syntax simply creates an alias for the specified symbol.
Expand All @@ -226,6 +250,7 @@ This is similar to using `var`, but also works on the type and namespace meaning
Importantly, for values, `import` is a distinct reference from the original symbol, so changes to an aliased `var` will not be reflected in the original variable.
# Working with Other JavaScript Libraries
<b><a href="#table-of-contents">↥ back to top</a></b>
To describe the shape of libraries not written in TypeScript, we need to declare the API that the library exposes.
Because most JavaScript libraries expose only a few top-level objects, namespaces are a good way to represent them.
Expand All @@ -236,6 +261,7 @@ If you're familiar with C/C++, you can think of these as `.h` files.
Let's look at a few examples.
## Ambient Namespaces
<b><a href="#table-of-contents">↥ back to top</a></b>
The popular library D3 defines its functionality in a global object called `d3`.
Because this library is loaded through a `<script>` tag (instead of a module loader), its declaration uses namespaces to define its shape.
Expand Down

0 comments on commit e3f69fe

Please sign in to comment.