Compare commits
3 commits
main
...
draft-spec
Author | SHA1 | Date | |
---|---|---|---|
d1e664d71b | |||
6920791ca8 | |||
4d185c84b3 |
78
doc/spec.md
78
doc/spec.md
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue