mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Proofreading
137
FAQ.md
137
FAQ.md
@@ -29,16 +29,16 @@
|
||||
- [Why do these empty classes behave strangely?](#why-do-these-empty-classes-behave-strangely)
|
||||
- [When and why are classes nominal?](#when-and-why-are-classes-nominal)
|
||||
- [Why does `this` get orphaned in my instance methods?](#why-does-this-get-orphaned-in-my-instance-methods)
|
||||
- [What's the difference between `Bar` and `typeof Bar` when `Bar` is a `class` ?](#whats-the-difference-between-bar-and-typeof-bar-when-bar-is-a-class-)
|
||||
- [What's the difference between `Bar` and `typeof Bar` when `Bar` is a `class`?](#whats-the-difference-between-bar-and-typeof-bar-when-bar-is-a-class)
|
||||
- [Why do my derived class property initializers overwrite values set in the base class constructor?](#why-do-my-derived-class-property-initializers-overwrite-values-set-in-the-base-class-constructor)
|
||||
- [What's the difference between `declare class` and `interface`?](#whats-the-difference-between-declare-class-and-interface)
|
||||
- [What does it mean for an interface to extend a class?](#what-does-it-mean-for-an-interface-to-extend-a-class)
|
||||
- [Why am I getting "TypeError: [base class name] is not defined in `__extends` ?](#why-am-i-getting-typeerror-base-class-name-is-not-defined-in-__extends-)
|
||||
- [Why am I getting "TypeError: Cannot read property 'prototype' of undefined" in `__extends` ?](#why-am-i-getting-typeerror-cannot-read-property-prototype-of-undefined-in-__extends-)
|
||||
- [Why am I getting "TypeError: [base class name] is not defined in `__extends`?](#why-am-i-getting-typeerror-base-class-name-is-not-defined-in-__extends)
|
||||
- [Why am I getting "TypeError: Cannot read property 'prototype' of undefined" in `__extends`?](#why-am-i-getting-typeerror-cannot-read-property-prototype-of-undefined-in-__extends)
|
||||
- [Why doesn't extending built-ins like `Error`, `Array`, and `Map` work?](#why-doesnt-extending-built-ins-like-error-array-and-map-work)
|
||||
- [Generics](#generics)
|
||||
- [Why is `A<string>` assignable to `A<number>` for `interface A<T> { }`?](#why-is-astring-assignable-to-anumber-for-interface-at--)
|
||||
- [Why doesn't type inference work on this interface: `interface Foo<T> { }` ?](#why-doesnt-type-inference-work-on-this-interface-interface-foot---)
|
||||
- [Why doesn't type inference work on this interface: `interface Foo<T> { }`?](#why-doesnt-type-inference-work-on-this-interface-interface-foot--)
|
||||
- [Why can't I write `typeof T`, `new T`, or `instanceof T` in my generic function?](#why-cant-i-write-typeof-t-new-t-or-instanceof-t-in-my-generic-function)
|
||||
- [Modules](#modules)
|
||||
- [Why are imports being elided in my emit?](#why-are-imports-being-elided-in-my-emit)
|
||||
@@ -50,9 +50,9 @@
|
||||
- [Why doesn't `isFoo(x)` narrow `x` to `Foo` when `isFoo` is a type guard?](#why-doesnt-isfoox-narrow-x-to-foo-when-isfoo-is-a-type-guard)
|
||||
- [Decorators](#decorators)
|
||||
- [Decorators on function declarations](#decorators-on-function-declarations)
|
||||
- [What's the difference between `@dec` and `@dec()` ? Shouldn't they be equivalent?](#whats-the-difference-between-dec-and-dec--shouldnt-they-be-equivalent)
|
||||
- [What's the difference between `@dec` and `@dec()`? Shouldn't they be equivalent?](#whats-the-difference-between-dec-and-dec-shouldnt-they-be-equivalent)
|
||||
- [JSX and React](#jsx-and-react)
|
||||
- [I wrote `declare var MyComponent: React.Component;`, why can't I write `<MyComponent />` ?](#i-wrote-declare-var-mycomponent-reactcomponent-why-cant-i-write-mycomponent--)
|
||||
- [I wrote `declare var MyComponent: React.Component;`, why can't I write `<MyComponent />`?](#i-wrote-declare-var-mycomponent-reactcomponent-why-cant-i-write-mycomponent-)
|
||||
- [Things That Don't Work](#things-that-dont-work)
|
||||
- [You should emit classes like this so they have real private members](#you-should-emit-classes-like-this-so-they-have-real-private-members)
|
||||
- [You should emit classes like this so they don't lose `this` in callbacks](#you-should-emit-classes-like-this-so-they-dont-lose-this-in-callbacks)
|
||||
@@ -62,7 +62,7 @@
|
||||
- [How do I write unit tests with TypeScript?](#how-do-i-write-unit-tests-with-typescript)
|
||||
- [Commandline Behavior](#commandline-behavior)
|
||||
- [Why did adding an `import` or `export` modifier break my program?](#why-did-adding-an-import-or-export-modifier-break-my-program)
|
||||
- [How do I control file ordering in combined output (`--out`) ?](#how-do-i-control-file-ordering-in-combined-output---out-)
|
||||
- [How do I control file ordering in combined output (`--out`)?](#how-do-i-control-file-ordering-in-combined-output---out)
|
||||
- [What does the error "Exported variable [name] has or is using private name [name]" mean?](#what-does-the-error-exported-variable-name-has-or-is-using-private-name-name-mean)
|
||||
- [Why does `--outDir` moves output after adding a new file?](#why-does---outdir-moves-output-after-adding-a-new-file)
|
||||
- [`tsconfig.json` Behavior](#tsconfigjson-behavior)
|
||||
@@ -86,26 +86,26 @@
|
||||
|
||||
> I've found a long-overlooked bug in TypeScript!
|
||||
|
||||
Here are some behaviors that look may look like bugs, but aren't.
|
||||
Here are some behaviors that may look like bugs, but aren't.
|
||||
|
||||
* These two empty classes can be used in place of each other
|
||||
* See the [FAQ Entry on this page](#why-do-these-empty-classes-behave-strangely)
|
||||
* I can use a non-`void`-returning function where one returning `void` is expected
|
||||
* See the [FAQ Entry on this page](#why-are-functions-returning-non-void-assignable-to-function-returning-void)
|
||||
* Prior discussion at #4544
|
||||
* I'm allowed to use a shorter parameter list where a longer one is expected
|
||||
* See the [FAQ Entry on this page](#why-are-functions-with-fewer-parameters-assignable-to-functions-that-take-more-parameters)
|
||||
* Prior discussion at #370, #9300, #9765, #9825, #13043, #16871, #13529, #13977, #17868, #20274, #20541, #21868, #26324, #30876
|
||||
* `private` class members are actually visible at runtime
|
||||
* See the [FAQ Entry on this page](#you-should-emit-classes-like-this-so-they-have-real-private-members) for a commonly suggested "fix"
|
||||
* Prior discussion at #564, #1537, #2967, #3151, #6748, #8847, #9733, #11033
|
||||
* These two empty classes can be used in place of each other
|
||||
* See the [FAQ Entry on this page](#why-do-these-empty-classes-behave-strangely)
|
||||
* I can use a non-`void`-returning function where one returning `void` is expected
|
||||
* See the [FAQ Entry on this page](#why-are-functions-returning-non-void-assignable-to-function-returning-void)
|
||||
* Prior discussion at #4544
|
||||
* I'm allowed to use a shorter parameter list where a longer one is expected
|
||||
* See the [FAQ Entry on this page](#why-are-functions-with-fewer-parameters-assignable-to-functions-that-take-more-parameters)
|
||||
* Prior discussion at #370, #9300, #9765, #9825, #13043, #16871, #13529, #13977, #17868, #20274, #20541, #21868, #26324, #30876
|
||||
* `private` class members are actually visible at runtime
|
||||
* See the [FAQ Entry on this page](#you-should-emit-classes-like-this-so-they-have-real-private-members) for a commonly suggested "fix"
|
||||
* Prior discussion at #564, #1537, #2967, #3151, #6748, #8847, #9733, #11033
|
||||
|
||||
## Common Feature Requests
|
||||
> I want to request one of the following features...
|
||||
|
||||
Here's a list of common feature requests and their corresponding issue.
|
||||
Please leave comments in these rather than logging new issues.
|
||||
* Safe navigation operator, AKA CoffeeScript's null conditional/propagating/propagation operator, AKA C#'s' ?. operator [#16](https://github.com/Microsoft/TypeScript/issues/16)
|
||||
* Safe navigation operator, AKA CoffeeScript's null conditional/propagating/propagation operator, AKA C#'s' `?.` operator [#16](https://github.com/Microsoft/TypeScript/issues/16)
|
||||
* Minification [#8](https://github.com/Microsoft/TypeScript/issues/8)
|
||||
* Extension methods [#9](https://github.com/Microsoft/TypeScript/issues/9)
|
||||
* Partial classes [#563](https://github.com/Microsoft/TypeScript/issues/563)
|
||||
@@ -185,17 +185,17 @@ See [#12](https://github.com/Microsoft/TypeScript/issues/12) for the suggestion
|
||||
This is an unsoundness resulting from the lack of explicit covariant/contravariant annotations in the type system.
|
||||
Because of this omission, TypeScript must be more permissive when asked whether `(x: Dog) => void` is assignable to `(x: Animal) => void`.
|
||||
|
||||
To understand why, consider two questions: Is `Dog[]` a subtype of `Animal[]` ? *Should* `Dog[]` be a subtype of `Animal[]` in TypeScript?
|
||||
To understand why, consider two questions: Is `Dog[]` a subtype of `Animal[]`? *Should* `Dog[]` be a subtype of `Animal[]` in TypeScript?
|
||||
|
||||
The second question (*should* `Dog[]` be a subtype of `Animal[]`?) is easier to analyze.
|
||||
What if the answer was "no" ?
|
||||
What if the answer was "no"?
|
||||
|
||||
```ts
|
||||
function checkIfAnimalsAreAwake(arr: Animal[]) { ... }
|
||||
|
||||
let myPets: Dog[] = [spot, fido];
|
||||
|
||||
// Error? Can't substitute Dog[] for Animal[] ?
|
||||
// Error? Can't substitute Dog[] for Animal[]?
|
||||
checkIfAnimalsAreAwake(myPets);
|
||||
```
|
||||
|
||||
@@ -206,10 +206,10 @@ There's not a good reason to reject this program on the basis that `Dog[]` can't
|
||||
Back to the first question.
|
||||
When the type system decides whether or not `Dog[]` is a subtype of `Animal[]`, it does the following computation (written here as if the compiler took no optimizations), among many others:
|
||||
|
||||
* Is `Dog[]` assignable to `Animal[]` ?
|
||||
* Is each member of `Dog[]` assignable to `Animal[]` ?
|
||||
* Is `Dog[]` assignable to `Animal[]`?
|
||||
* Is each member of `Dog[]` assignable to `Animal[]`?
|
||||
* Is `Dog[].push` assignable to `Animal[].push`?
|
||||
* Is the type `(x: Dog) => number` assignable to `(x: Animal) => number` ?
|
||||
* Is the type `(x: Dog) => number` assignable to `(x: Animal) => number`?
|
||||
* Is the first parameter type in `(x: Dog) => number` assignable to or from first parameter type in `(x: Animal) => number`?
|
||||
* Is `Dog` assignable to or from `Animal`?
|
||||
* Yes.
|
||||
@@ -264,9 +264,9 @@ The meaning of an optional callback parameter is *this*:
|
||||
// Invoke the provided function with 0 or 1 argument
|
||||
function maybeCallWithArg(callback: (x?: number) => void) {
|
||||
if (Math.random() > 0.5) {
|
||||
callback();
|
||||
callback();
|
||||
} else {
|
||||
callback(42);
|
||||
callback(42);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -536,7 +536,7 @@ One of the most useful cases is functions:
|
||||
var x: (n: string) => void = (s) => console.log(s.ToUpper());
|
||||
```
|
||||
|
||||
How did the compiler know that `s` was a `string`? If you wrote that function expression by itself, `s` would be of type `any` and there wouldn't be any error issued. But because the function was contextually typed by the type of `x`, the parameter s acquired the type `string`. Very useful!
|
||||
How did the compiler know that `s` was a `string`? If you wrote that function expression by itself, `s` would be of type `any` and there wouldn't be any error issued. But because the function was contextually typed by the type of `x`, the parameter `s` acquired the type `string`. Very useful!
|
||||
|
||||
At the same time, an index signature specifies the type when an object is indexed by a `string` or a `number`. Naturally, these signatures are part of type checking:
|
||||
|
||||
@@ -643,8 +643,8 @@ The syntax `f({x: number})` declares a destructuring *from the property* `x` *to
|
||||
Looking at the emitted code for this is instructive:
|
||||
```ts
|
||||
function f(_a) {
|
||||
// Not really what we were going for
|
||||
var number = _a.x;
|
||||
// Not really what we were going for
|
||||
var number = _a.x;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -738,11 +738,11 @@ Synonyms and alternate symptoms:
|
||||
> * Why does `this` point to `window` in my callback?
|
||||
> * Why does `this` point to `undefined` in my callback?
|
||||
> * Why am I getting an error `this.someMethod is not a function`?
|
||||
> * Why am I getting an error `Cannot read property 'someMethod' of undefined` ?
|
||||
> * Why am I getting an error `Cannot read property 'someMethod' of undefined`?
|
||||
|
||||
In JavaScript, the value of `this` inside a function is determined as follows:
|
||||
1. Was the function the result of calling `.bind`? If so, `this` is the first argument passed to `bind`
|
||||
2. Was the function *directly* invoked via a property access expression `expr.method()` ? If so, `this` is `expr`
|
||||
2. Was the function *directly* invoked via a property access expression `expr.method()`? If so, `this` is `expr`
|
||||
3. Otherwise, `this` is `undefined` (in "strict" mode), or `window` in non-strict mode
|
||||
|
||||
The offending problem is this line of code:
|
||||
@@ -755,7 +755,7 @@ Thus, `this` in the body of `someCallback` referred to `window` (or `undefined`
|
||||
|
||||
Solutions to this are outlined here: http://stackoverflow.com/a/20627988/1704166
|
||||
|
||||
### What's the difference between `Bar` and `typeof Bar` when `Bar` is a `class` ?
|
||||
### What's the difference between `Bar` and `typeof Bar` when `Bar` is a `class`?
|
||||
> I wrote some code like this and don't understand the error I'm getting:
|
||||
> ```ts
|
||||
> class MyClass {
|
||||
@@ -772,10 +772,10 @@ When a constructor function is invoked with `new`, we get back an object that is
|
||||
|
||||
So when we define a class, we actually define two different *types*.
|
||||
|
||||
The first is the one referred to by the class's name; in this case, `MyClass`.
|
||||
The first is the one referred to by the class' name; in this case, `MyClass`.
|
||||
This is the *instance* type of the class.
|
||||
It defines the properties and methods that an *instance* of the class has.
|
||||
It's the type returned by invoking the class's constructor.
|
||||
It's the type returned by invoking the class' constructor.
|
||||
|
||||
The second type is anonymous.
|
||||
It is the type that the constructor function has.
|
||||
@@ -814,10 +814,10 @@ See http://stackoverflow.com/a/14348084/1704166
|
||||
|
||||
This makes a type called `Bar` that has the same members as the instance shape of `Foo`.
|
||||
However, if `Foo` has private members, their corresponding properties in `Bar` must be implemented
|
||||
by a class which has `Foo` in its heritage.
|
||||
by a class which has `Foo` in its heritage.
|
||||
In general, this pattern is best avoided, especially if `Foo` has private members.
|
||||
|
||||
### Why am I getting "TypeError: [base class name] is not defined in `__extends` ?
|
||||
### Why am I getting "TypeError: [base class name] is not defined in `__extends`?
|
||||
> I wrote some code like this:
|
||||
> ```ts
|
||||
> /** file1.ts **/
|
||||
@@ -832,9 +832,9 @@ In general, this pattern is best avoided, especially if `Foo` has private member
|
||||
> ```
|
||||
|
||||
The most common cause of this is that your HTML page includes a `<script>` tag for file2.ts, but not file1.ts.
|
||||
Add a script tag for the base class's output *before* the script tag for the derived class.
|
||||
Add a script tag for the base class' output *before* the script tag for the derived class.
|
||||
|
||||
### Why am I getting "TypeError: Cannot read property 'prototype' of undefined" in `__extends` ?
|
||||
### Why am I getting "TypeError: Cannot read property 'prototype' of undefined" in `__extends`?
|
||||
> I wrote some code:
|
||||
> ```ts
|
||||
> /** file1.ts **/
|
||||
@@ -943,13 +943,13 @@ But because `Something<T>` doesn't *use* `T` in any member, it doesn't matter wh
|
||||
In general, you should *never* have type parameters which are unused.
|
||||
The type will have unexpected compatibility (as shown here) and will also fail to have proper generic type inference in function calls.
|
||||
|
||||
### Why doesn't type inference work on this interface: `interface Foo<T> { }` ?
|
||||
### Why doesn't type inference work on this interface: `interface Foo<T> { }`?
|
||||
|
||||
> I wrote some code like this:
|
||||
>
|
||||
> ```ts
|
||||
> interface Named<T> {
|
||||
> name: string;
|
||||
> name: string;
|
||||
> }
|
||||
> class MyNamed<T> implements Named<T> {
|
||||
> name: 'mine';
|
||||
@@ -971,7 +971,7 @@ Because there are no members which use `T`, there is nothing to infer from, so w
|
||||
Note that if you use `T`, you get correct inference:
|
||||
```ts
|
||||
interface Named<T> {
|
||||
name: string;
|
||||
name: string;
|
||||
value: T; // <-- added
|
||||
}
|
||||
class MyNamed<T> implements Named<T> {
|
||||
@@ -1014,7 +1014,7 @@ In both cases, using a *construct signature* and providing it as a parameter wil
|
||||
|
||||
```ts
|
||||
function create<T>(ctor: { new(): T }) {
|
||||
return new ctor();
|
||||
return new ctor();
|
||||
}
|
||||
var c = create(MyClass); // c: MyClass
|
||||
|
||||
@@ -1110,14 +1110,14 @@ TODO, but it is strongly related to the above section.
|
||||
### Decorators on function declarations
|
||||
TODO: Answer. Also, what did we mean here?
|
||||
|
||||
### What's the difference between `@dec` and `@dec()` ? Shouldn't they be equivalent?
|
||||
### What's the difference between `@dec` and `@dec()`? Shouldn't they be equivalent?
|
||||
TODO: Answer
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
## JSX and React
|
||||
|
||||
### I wrote `declare var MyComponent: React.Component;`, why can't I write `<MyComponent />` ?
|
||||
### I wrote `declare var MyComponent: React.Component;`, why can't I write `<MyComponent />`?
|
||||
|
||||
> I wrote some code like this. Why is there an error?
|
||||
> ```ts
|
||||
@@ -1142,7 +1142,9 @@ let jsx = <SomeThing />; // Not gonna work
|
||||
```
|
||||
|
||||
The easiest fix is to use the `typeof` type operator.
|
||||
> let SomeThing: typeof Display = /* ... */;
|
||||
```ts
|
||||
let SomeThing: typeof Display = /* ... */;
|
||||
```
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
|
||||
@@ -1189,17 +1191,17 @@ a.increment(); // Prints 1
|
||||
> If I write code like this:
|
||||
> ```ts
|
||||
> class MyClass {
|
||||
> method() {
|
||||
> }
|
||||
> method() {
|
||||
> }
|
||||
> }
|
||||
> ```
|
||||
> You should emit code like this so that I can't mess up `this` in in callbacks:
|
||||
> You should emit code like this so that I can't mess up `this` in callbacks:
|
||||
> ```js
|
||||
> var MyClass = (function () {
|
||||
> function MyClass() {
|
||||
> this.method = function() {
|
||||
> this.method = function() {
|
||||
>
|
||||
> }
|
||||
> }
|
||||
> }
|
||||
> return MyClass;
|
||||
> })();
|
||||
@@ -1212,7 +1214,7 @@ There isn't really anything else to be said on that front -- TypeScript must hav
|
||||
|
||||
Second, the runtime characteristics of this class are very surprising.
|
||||
Instead of allocating one closure per method, this allocates one closure per method *per instance*.
|
||||
This expensive in terms of class initialization cost, memory pressure, and GC performance.
|
||||
This is expensive in terms of class initialization cost, memory pressure, and GC performance.
|
||||
|
||||
### Why can't I access arbitrary properties on a type with a string indexer?
|
||||
|
||||
@@ -1230,7 +1232,7 @@ This expensive in terms of class initialization cost, memory pressure, and GC pe
|
||||
> Instead I can only use index syntax: `obj['foo']`.
|
||||
|
||||
The point of TypeScript is to catch errors at compile-time, and "Property does not exist" is one of the most important.
|
||||
If a string indexer let you access properties on a type, you'd never get this error for those types.
|
||||
If a string indexer lets you access properties on a type, you'd never get this error for those types.
|
||||
This is important if you have other properties on the indexed type:
|
||||
|
||||
```ts
|
||||
@@ -1300,7 +1302,7 @@ In this case, you should be running `node myApp.js`, because the *module* `myApp
|
||||
|
||||
This behavior has been fixed as of TypeScript 1.8; combining `--out` and `--module` is now an error for CommonJS module output.
|
||||
|
||||
### How do I control file ordering in combined output (`--out`) ?
|
||||
### How do I control file ordering in combined output (`--out`)?
|
||||
|
||||
The order of the generated files in the output follows that of the input files after the pre-processing pass.
|
||||
|
||||
@@ -1357,11 +1359,11 @@ To ensure the output does not change with adding new files specify `--rootDir` o
|
||||
|
||||
### Why is a file in the `exclude` list still picked up by the compiler?
|
||||
|
||||
`tsconfig.json` turns a folder into a “project”. Without specifying any `“exclude”` or `“files”` entries, all files in the folder containing the `tsconfig.json` and all its sub-directories are included in your compilation.
|
||||
`tsconfig.json` turns a folder into a "project". Without specifying any `"exclude"` or `"files"` entries, all files in the folder containing the `tsconfig.json` and all its sub-directories are included in your compilation.
|
||||
|
||||
If you want to exclude some of the files use `“exclude”`, if you would rather specify all the files instead of letting the compiler look them up, use `“files”`.
|
||||
If you want to exclude some of the files, use `"exclude"`. If you would rather specify all the files instead of letting the compiler look them up, use `"files"`.
|
||||
|
||||
That was `tsconfig.json` automatic inclusion. There is a different issue, which is module resolution. By module resolution, I mean the compiler trying to understand what `ns` means in an import statement like: `import * ns from “mod”`. To do so, the compiler needs the definition of a module, this could be a .ts file for your own code, or a .d.ts for an imported definition file. if the file was found, it will be included regardless if it was excluded in the previous steps.
|
||||
That was `tsconfig.json` automatic inclusion. There is a different issue, which is module resolution. By module resolution, I mean the compiler trying to understand what `ns` means in an import statement like: `import * ns from "mod"`. To do so, the compiler needs the definition of a module, this could be a .ts file for your own code, or a .d.ts for an imported definition file. If the file was found, it will be included regardless of whether it was excluded in the previous steps or not.
|
||||
|
||||
So to exclude a file from the compilation, you need to exclude and all **all** files that have an `import` or `/// <reference path="..." />` directives to them.
|
||||
|
||||
@@ -1369,7 +1371,10 @@ Use `tsc --listFiles` to list what files are included in your compilation, and `
|
||||
|
||||
### How can I specify an `include`?
|
||||
|
||||
There is no way now to indicate an `“include”` to a file outside the current folder in the `tsconfig.json` (tracked by [#1927](https://github.com/Microsoft/TypeScript/issues/1927)). You can achieve the same result by either: 1. Using a `“files”` list, or 2. Adding a `/// <reference path="..." />` directive in one of the files in your directory.
|
||||
There is no way now to indicate an `"include"` to a file outside the current folder in the `tsconfig.json` (tracked by [#1927](https://github.com/Microsoft/TypeScript/issues/1927)). You can achieve the same result by either:
|
||||
|
||||
1. Using a `"files"` list, or ;
|
||||
2. Adding a `/// <reference path="..." />` directive in one of the files in your directory.
|
||||
|
||||
### Why am I getting the `error TS5055: Cannot write file 'xxx.js' because it would overwrite input file.` when using JavaScript files?
|
||||
|
||||
@@ -1389,7 +1394,7 @@ If you just want to include the JavaScript files for editing and don't need to c
|
||||
TypeScript compiler uses a position of a node in the abstract syntax tree to retrieve its comments during emit.
|
||||
Because the compiler does not store all tokens into the tree, some comments may be missed in an output JavaScript file.
|
||||
For example, we do not store following tokens into the tree `,`, `{`, `}`, `(`, `)`.
|
||||
Therefore, trailing comments or leading comments of such token cannot be retrieved during emit.
|
||||
Therefore, trailing comments or leading comments of such tokens cannot be retrieved during emit.
|
||||
At the moment, there is not an easy method to preserve such comments without storing those tokens.
|
||||
Doing so, however, can significantly increase the tree size and potentially have performance impact.
|
||||
|
||||
@@ -1448,7 +1453,7 @@ Other examples will use DOM types like `HTMLElement` and `HTMLDivElement` to hig
|
||||
|
||||
### "Substitutability"
|
||||
Many answers relating to the type system make reference to [Substitutability](https://en.wikipedia.org/wiki/Liskov_substitution_principle).
|
||||
This is a principle that says if an object `X` can be used in place of some object `Y`, then `X` is a *subtype* of `Y`.
|
||||
This is a principle that says that if an object `X` can be used in place of some object `Y`, then `X` is a *subtype* of `Y`.
|
||||
We also commonly say that `X` is *assignable to* `Y` (these terms have slightly different meanings in TypeScript, but the difference is not important here).
|
||||
|
||||
In other words, if I ask for a `fork`, a `spork` is an acceptable *substitute* because it has the same functions and properties of a `fork` (three prongs and a handle).
|
||||
@@ -1460,11 +1465,11 @@ TypeScript classifies comments into three different types:
|
||||
- Trailing comment : a comment after a node and in the same line as the node.
|
||||
- Detached comment : a comment that is not part of any node such as copyright comment.
|
||||
```ts
|
||||
/*! Top-of-file copyright comment is a detached comment*/
|
||||
/*! Top-of-file copyright comment is a detached comment */
|
||||
|
||||
/* Leading comments of the function AST node*/
|
||||
function foo /*trailing comments of the function name, "foo", AST node*/ () {
|
||||
/* Detached comment*/
|
||||
/* Leading comments of the function AST node */
|
||||
function foo /* trailing comments of the function name, "foo", AST node */ () {
|
||||
/* Detached comment */
|
||||
|
||||
let x = 10;
|
||||
}
|
||||
@@ -1522,7 +1527,7 @@ Having a record of these use cases helps us reprioritize.
|
||||
Specifically, remember that the TypeScript team does not have the resources to continuously relitigate closed suggestions.
|
||||
|
||||
*Bargaining*: Ask yourself: is there a smaller thing that would work?
|
||||
Many suggestions are simply too large of a hammer for too small of a nail.
|
||||
Many suggestions are simply too large of a hammer or too small of a nail.
|
||||
Think about the problem you're experiencing for a while and see if you can come up with a simpler solution that accomplishes the same goal.
|
||||
|
||||
*Depression*: Try not to be depressed about declined suggestions.
|
||||
|
||||
Reference in New Issue
Block a user