Compare commits

...

3 commits

Author SHA1 Message Date
Nathan Shively-Sanders d1e664d71b Skeleton of literal widening section 2017-12-12 13:29:52 -08:00
Nathan Shively-Sanders 6920791ca8 Update todos los TODOs 2017-12-07 15:46:50 -08:00
Nathan Shively-Sanders 4d185c84b3 Updated skeleton of literal/unit types 2017-12-07 11:29:31 -08:00

View file

@ -1149,7 +1149,13 @@ The only possible values for the Void type are `null` and `undefined`. The Void
*NOTE: We might consider disallowing declaring variables of type Void as they serve no useful purpose. However, because Void is permitted as a type argument to a generic type or function it is not feasible to disallow Void properties or parameters*.
### <a name="3.2.6"/>3.2.6 The Null Type
### Unit Types { #unit-types }
Unit types are types with a single value. The unit types in TypeScript are `null`, `undefined`, string literal types, number literal types and boolean literal types.
TODO: Update the null and undefined sections in my other draft PR.
#### The Null Type { #null-type }
The Null type corresponds to the similarly named JavaScript primitive type and is the type of the `null` literal.
@ -1165,7 +1171,7 @@ var x = null; // Same as x: any = null
var e: Null; // Error, can't reference Null type
```
### <a name="3.2.7"/>3.2.7 The Undefined Type
#### The Undefined Type { #undefined-type }
The Undefined type corresponds to the similarly named JavaScript primitive type and is the type of the `undefined` literal.
@ -1181,19 +1187,36 @@ var x = undefined; // Same as x: any = undefined
var e: Undefined; // Error, can't reference Undefined type
```
#### Literal types { #literal-types }
TypeScript supports string, number and boolean literal types, but not regular expression literal types.
Literal types use the syntax of their respective literal values.
For example, the boolean literal type `true` uses the same keyword as the boolean literal value `true`.
Similarly, literal types are subclasses of their respective literal values' types:
* The supertype of the literal types `true` and `false` is the Boolean primitive type.
* The supertype of numeric literal types is the Number primitive type.
* The supertype of string literal types is the String primitive type.
TODO: Maybe a note about the numeric syntax since that support is a bit wobbly.
#### Example with unions and narrowing
TODO: An ADT example here.
### <a name="3.2.8"/>3.2.8 Enum Types
Enum types are distinct user defined subtypes of the Number primitive type. Enum types are declared using enum declarations (section [9.1](#9.1)) and referenced using type references (section [3.8.2](#3.8.2)).
Enum types are assignable to the Number primitive type, and vice versa, but different enum types are not assignable to each other.
### <a name="3.2.9"/>3.2.9 String Literal Types
Specialized signatures (section [3.9.2.4](#3.9.2.4)) permit string literals to be used as types in parameter type annotations. String literal types are permitted only in that context and nowhere else.
All string literal types are subtypes of the String primitive type.
*TODO: Update to reflect [expanded support for string literal types](https://github.com/Microsoft/TypeScript/pull/5185)*.
TODO: This section should be updated to discuss:
1. Normal versus Const enums
2. Computed versus Union enums
3. Exceptions to enum nominality
4. Union enums in detail
5. Enum type relations to the number type.
## <a name="3.3"/>3.3 Object Types
@ -2476,17 +2499,40 @@ In several situations TypeScript infers types from context, alleviating the need
var name = "Steve";
```
infers the type of 'name' to be the String primitive type since that is the type of the value used to initialize it. When inferring the type of a variable, property or function result from an expression, the ***widened*** form of the source type is used as the inferred type of the target. The widened form of a type is the type in which all occurrences of the Null and Undefined types have been replaced with the type `any`.
infers the type of 'name' to be the String type since that is the type of the value used to initialize it.
When inferring the type of a variable, property or function result from an expression, the ***widened*** form of the source type is used as the inferred type of the target.
The widened form of a type is the type in which all literal types have been replaced with their base types, according to the following rule:
The following example shows the results of widening types to produce inferred variable types.
If the type is:
* A string literal type, the result is the String type
* A number literal type, the result is the Number type.
* A boolean literal type, the result is the Boolean type.
* A union type, the result is the widened type of each of its members.
* Any other type, the result is the original type.
```TypeScript
var a = null; // var a: any
var b = undefined; // var b: any
var c = { x: 0, y: null }; // var c: { x: number, y: any }
var d = [ null, undefined ]; // var d: any[]
Note that literal types that arise from type syntax do not widen. That is,
```ts
let choice: "yes" | "no";
```
declares a variable with the type `"yes" | "no"`, not the type string.
Literal types that arise from expressions are initially *fresh*. Fresh literal types widen in certain (TODO: Define!) locations.
Literal types lose their freshness at other locations (TODO: Define!).
These types will no longer widen.
Places that literal types lose freshness:
* Calls to getRegularTypeOfObjectLiteral (duh)
* When added to an intersection (when does this happen?)
* Case clause expressions
*
Places that literal types widen (generally mutable locations):
* getWidenedTypeFromJSSpecialPropertyDeclarations (this.x = 'hi', p.x = 'hi', etc?)
Here's an example
<br/>
# <a name="4"/>4 Expressions