Skip to content

Commit 1a4eead

Browse files
committed
Update to only include units of measure
Made changes based on this thread: microsoft/TypeScript#364 - Added more examples - Removed tiny types (maybe this can be added in later?)
1 parent 9318d55 commit 1a4eead

File tree

1 file changed

+97
-51
lines changed

1 file changed

+97
-51
lines changed

README.md

Lines changed: 97 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,101 +7,147 @@ Units of Measure: Proposal for TypeScript
77

88
Units of measure is a useful [F# feature](http://msdn.microsoft.com/en-us/library/dd233243.aspx) that provides the optional ability to create tighter constraints on floating point and signed integer values.
99

10-
TypeScript could benefit from a similar units of measure feature and expand to include tiny type support for `string`, `boolean`, and `date` objects. Such a feature would add zero runtime overhead, increase type constraints, and help decrease programmer error.
10+
TypeScript could benefit from a similar units of measure feature. Such a feature would add zero runtime overhead, increase type constraints, and help decrease programmer error.
1111

12-
## Defining Type Annotations
12+
## Defining Units of Measure
1313

14-
Type annotations are defined as such:
14+
Units of measure are defined as such:
1515

1616
```typescript
17-
type <annotation-name> [extends <type-name>] [ = measure ];
17+
unit <unit-name> [ = unit ];
1818
```
1919

20-
The optional measure part can be used to define a new types in terms of previously defined types. Note that this composite type cannot be used with non-`number` types.
20+
The optional unit part can be used to define a new unit in terms of previously defined units.
2121

22-
**Examples:**
22+
The `<unit-name>` is unique so there cannot be any other types or variables defined with the same name within the unit's scope. For example, the following would not be valid:
2323

2424
```typescript
25-
type m extends number;
26-
type s extends number;
27-
type a = m/s^2;
28-
type email extends string;
25+
var m = 10;
26+
27+
unit m; // error
28+
```
29+
30+
### Example Definitions
31+
32+
```typescript
33+
unit m;
34+
unit s;
35+
unit a = m/s^2;
2936
```
3037

3138
Note: The caret symbol does not denote a bitwise XOR operator, but rather an exponent. In this case, `m/s^2` is equivalent to `m/s/s`.
3239

33-
## Use with Number
40+
### Circular Definitions
41+
42+
Circular definitions are NOT allowed. For example:
43+
44+
```typescript
45+
unit a = b / c;
46+
unit b = a * c;
47+
unit c = b / a;
48+
```
49+
50+
## Using units
3451

3552
```typescript
36-
type m extends number;
37-
type s extends number;
38-
type a = m/s^2;
53+
unit m;
54+
unit s;
55+
unit a = m/s^2;
3956

4057
var acceleration = 12<a>,
41-
time = 10<s>;
58+
time = new Number(10)<s>;
4259

4360
var distance = 1/2 * acceleration * time * time; // valid -- implicitly typed to number<m>
4461
var avgSpeed = distance / time; // valid -- implicitly typed to number<m/s>
4562

4663
time += 5<s>; // valid
47-
time += 5; // compile error -- Cannot convert number to number<s>
48-
time += distance; // compile error -- Cannot convert number<m> to number<s>
64+
time += 5; // error -- cannot convert number to number<s>
65+
time += distance; // error -- cannot convert number<m> to number<s>
4966

5067
acceleration += 12<m/s^2>; // valid
5168
acceleration += 10<a>; // valid
52-
acceleration += 12<m/s^2> * 10<s>; // compile error -- Cannot convert number<m/s> to number<a>
69+
acceleration += 12<m/s^2> * 10<s>; // error -- cannot convert number<m/s> to number<a>
5370
```
5471

55-
## Use with String, Boolean, and Date
72+
### Use With Non-Unit of Measure Number Types
5673

57-
```typescript
58-
type email extends string;
74+
Sometimes legacy code or external libraries will return number types without a unit of measure. In these cases, it is useful to allow the programmer to specify the unit like so:
5975

60-
function sendEmail(email: string<email>, message : string) {
61-
// send the email in here
62-
}
76+
```typescript
77+
unit s;
6378

64-
var myEmail = "[email protected]"<email>;
65-
sendEmail(myEmail, "Hello!"); // valid
66-
sendEmail("some string", "Hello!"); // compile error -- Cannot convert string to string<email>
79+
var time = 3<s>,
80+
num = 4;
81+
82+
time = time + num; // error -- cannot add number to number<s>
83+
time = time + num<s>; // valid
6784
```
6885

69-
The following is invalid:
86+
## Dimensionless Unit
87+
88+
A dimensionless unit is a unit of measure defined as `number<1>`.
7089

7190
```typescript
72-
type m extends number;
73-
type s extends number;
74-
type a = m/s^2;
91+
var ratio = 10<s> / 20<s>, // implicitly typed to number<1>
92+
time : number<s>;
7593

76-
var myString : string<a>; // compile error -- Cannot use number types with a string
94+
time = 2<s> * ratio;
95+
time *= ratio;
96+
time = 2<s> + ratio; // error, cannot add number<1> to number<s>
97+
time = ratio; // error, cannot assign number<1> to number<s>
7798
```
7899

79-
## Additional Cases
100+
## Math Library
101+
102+
Units of measure should work well with the current existing [Math object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math).
103+
104+
Some examples:
80105

81106
```typescript
82-
type m extends number;
83-
type email extends string;
84-
type startDate extends Date;
85-
type flag extends boolean;
86-
87-
var num = new Number<m>(),
88-
str = new String<email>(),
89-
date = new Date<startDate>(),
90-
b = new Boolean<flag>();
107+
Math.min(0<s>, 4<m>); // error, cannot mix number<s> with number<m>
108+
109+
var volume = Math.pow(2<m>, 3); // volume is implicitly typed to number<m^3>
91110
```
92111

93-
## Additional Considerations
112+
## Outstanding Questions
113+
114+
As discussed in [this thread](https://github.com/Microsoft/TypeScript/issues/364#issuecomment-51720786).
115+
116+
### 1. How does units of measure work when used across modules?
117+
118+
#### Suggestion #1
94119

95-
The defintion statement could also be like one of the following (or a combination of):
120+
> A measure is in the scope of a module. Outside the module it is not visible. When using external modules, you should create measures in a .d.ts file.
121+
122+
-- [ivogabe](https://github.com/Microsoft/TypeScript/issues/364#issuecomment-51711138)
123+
124+
#### Suggestion #2
125+
126+
> Just throwing out some ideas here, but maybe measures could be imported in order to prevent conflicts between libraries... so you would have to write something like `import unit m = MyMeasureModule.m;` at the top of each file you want to use it. Then when you're writing a measure in a module you would do this:
96127
97128
```typescript
98-
type string<email>;
99-
declare type email : string;
129+
module MyModule {
130+
export unit m; // or maybe these could also be defined at the class level
131+
export unit s;
132+
133+
export class MyClass {
134+
myMethod() : number<m/s> {
135+
return 20<m/s>;
136+
}
137+
}
138+
}
100139
```
101140

102-
## Supported Types
141+
> That could help prevent conflicts because you could do `import unit m = MyMeasureModule.m` and `import unit meters = SomeOtherLibrary.m`, but it wouldn't be so nice when a conflict occurs. Additionally, it wouldn't be that nice to have to rewrite measure statements at the top of each file you want to use them in, but I guess it's not too bad (think of it like the necessity of writing using statements in c#).
103142
104-
* String
105-
* Number
106-
* Boolean
107-
* Date
143+
-- [dsherret](https://github.com/Microsoft/TypeScript/issues/364#issuecomment-51716846)
144+
145+
146+
### 2. How can a function return a new combination of the units of measure used?
147+
148+
For example, how would the `Math.pow` function be defined?
149+
150+
```typescript
151+
pow<u ^ pow>(base : number<u>, pow : number) {
152+
}
153+
```

0 commit comments

Comments
 (0)