Skip to content

Commit

Permalink
Reimplement dtslint (#89)
Browse files Browse the repository at this point in the history
  • Loading branch information
jscheiny authored Nov 16, 2018
1 parent eecac11 commit 4292a95
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 10 deletions.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
"compile:src": "tsc -p src",
"lint:codegen": "tslint -p codegen/tsconfig.json -c tslint.json",
"lint:src": "tslint -p src/tsconfig.json -c tslint.json",
"lint:types": "./scripts/check-typings.sh",
"lint": "npm-run-all -p lint:codegen lint:src lint:types",
"lint:dist": "./scripts/check-typings.sh",
"lint:types": "dtslint test/types",
"lint": "npm-run-all -p lint:codegen lint:src lint:dist lint:types",
"node:codegen": "node codegen/dist/emit",
"test": "jest --config jest.config.json",
"prepack": "yarn build",
Expand All @@ -36,6 +37,7 @@
"devDependencies": {
"@types/jest": "^22.2.3",
"@types/node": "^8.10.16",
"dtslint": "^0.3.0",
"jest": "^22.4.3",
"npm-run-all": "^4.1.3",
"prettier": "^1.12.1",
Expand Down
2 changes: 2 additions & 0 deletions src/exponent/exponentArithmetic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { DivideExponents } from "./generated/division";
import { Exponent } from "./generated/exponent";
import { MultiplyExponents } from "./generated/multiplication";

export type NonZeroExponent = Exclude<Exponent, 0>;

type SubtractExponents<L extends Exponent, R extends Exponent> = AddExponents<L, Negative<R>>;
type Negative<N extends Exponent> = MultiplyExponents<N, -1>;

Expand Down
9 changes: 5 additions & 4 deletions src/measure/unitTypeArithmetic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Exponent,
MultiplicandOf,
MultiplyExponents,
NonZeroExponent,
ProductOf,
} from "../exponent";

Expand Down Expand Up @@ -50,9 +51,9 @@ export interface BaseUnit<N extends Exponent> {
// Roots

/** Returns the nth root of a unit. This is the inverse scalar multiple of the dimension vector. */
export type NthRootUnit<U extends Unit, N extends Exponent> = StripZeroes<
{ [Dim in keyof U]: DivideExponents<GetExponent<U, Dim>, N> }
>;
export type NthRootUnit<U extends Unit, N extends NonZeroExponent> = 1 extends N
? U
: { [Dim in keyof U]: DivideExponents<GetExponent<U, Dim>, N> };

/** A type that is assignable from all units whose Nth root does not produce an error. */
export interface RadicandUnit<N extends Exponent> {
Expand All @@ -68,4 +69,4 @@ type StripZeroes<U extends Unit> = { [Dim in NonZeroKeys<U>]: U[Dim] };
type NonZeroKeys<U extends Unit> = { [Dim in keyof U]: NonNullable<U[Dim]> extends 0 ? never : Dim }[keyof U];

/** Get the exponent at a given dimension of a unit, or 0 if that dimension is undefined */
type GetExponent<U extends Unit, D> = D extends keyof Unit ? (undefined extends U[D] ? 0 : NonNullable<U[D]>) : 0;
export type GetExponent<U extends Unit, D> = D extends keyof U ? NonNullable<U[D]> : 0;
4 changes: 2 additions & 2 deletions src/measure/unitValueArithmetic.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Exponent } from "../exponent";
import { Exponent, NonZeroExponent } from "../exponent";
import {
BaseUnit,
DivideUnits,
Expand Down Expand Up @@ -70,7 +70,7 @@ export function exponentiateUnit<U extends BaseUnit<N>, N extends Exponent>(
return expAndRootImpl(unit, exponent => exponent * power);
}

export function nthRootUnit<U extends RadicandUnit<N>, N extends Exponent>(
export function nthRootUnit<U extends RadicandUnit<N>, N extends NonZeroExponent>(
unit: UnitWithSymbols<U>,
root: N,
): UnitWithSymbols<NthRootUnit<U, N>> {
Expand Down
1 change: 1 addition & 0 deletions test/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// TypeScript Version: 2.9
16 changes: 16 additions & 0 deletions test/types/measuresErrors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Area, Measure, Volume } from "safe-units";

Volume.times(Volume); // $ExpectError
const volumeInverse = Volume.inverse();
Volume.over(volumeInverse); // $ExpectError

Volume.plus(Area); // $ExpectError
Area.minus(Volume); // $ExpectError

const s = Volume.squared; // $ExpectType never
const c = Area.cubed; // $ExpectType never
Area.toThe(4); // $ExpectType never
Volume.toThe(-2); // $ExpectType never

Measure.sqrt(Volume); // $ExpectError
Measure.cbrt(Area); // $ExpectError
26 changes: 26 additions & 0 deletions test/types/measuresValid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Acceleration, kilograms, Measure, meters, newtons, seconds, Velocity } from "safe-units";

Measure.dimension("x"); // $ExpectType GenericMeasure<number, { x: 1; }>

const m = meters; // $ExpectType GenericMeasure<number, { length: 1; }>
const s = seconds; // $ExpectType GenericMeasure<number, { time: 1; }>
const n = newtons; // $ExpectType GenericMeasure<number, StripZeroes<{ length: 1; time: -2; mass: 1; }>>

const a = newtons.over(kilograms); // $ExpectType GenericMeasure<number, StripZeroes<{ length: 1; time: -2; mass: 0; }>>
const accel: Acceleration = a; // $ExpectType GenericMeasure<number, StripZeroes<{ length: 1; time: -2; mass: 0; }>>

const absement = meters.times(seconds); // $ExpectType GenericMeasure<number, StripZeroes<{ length: 1; time: 1; }>>
const velocity = meters.over(seconds); // $ExpectType GenericMeasure<number, StripZeroes<{ length: 1; time: -1; }>>

meters.plus(meters); // $ExpectType GenericMeasure<number, { length: 1; }>
meters.minus(meters); // $ExpectType GenericMeasure<number, { length: 1; }>
meters.negate(); // $ExpectType GenericMeasure<number, { length: 1; }>
meters.scale(2); // $ExpectType GenericMeasure<number, { length: 1; }>

velocity.squared(); // $ExpectType GenericMeasure<number, { length: 2; time: -2; }>
absement.cubed(); // $ExpectType GenericMeasure<number, { length: 3; time: 3; }>
absement.inverse(); // $ExpectType GenericMeasure<number, { length: -1; time: -1; }>
velocity.toThe(0); // $ExpectType GenericMeasure<number, {}>

Measure.sqrt(velocity.toThe(-4)); // $ExpectType GenericMeasure<number, { length: -2; time: 2; }>
Measure.cbrt(absement.toThe(3)); // $ExpectType GenericMeasure<number, { length: 1; time: 1; }>
16 changes: 16 additions & 0 deletions test/types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"declaration": true,
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": false,
"lib": ["es5"],
"baseUrl": ".",
"paths": { "safe-units": ["../../src"] }
}
}
6 changes: 6 additions & 0 deletions test/types/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "dtslint/dtslint.json",
"rules": {
"no-useless-files": false
}
}
116 changes: 114 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@
version "8.10.16"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.16.tgz#96fadb371748845a0c8ea970a565330efb0a67d5"

"@types/parsimmon@^1.3.0":
version "1.10.0"
resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.0.tgz#ffb81cb023ff435a41d4710a29ab23c561dc9fdf"
integrity sha512-bsTIJFVQv7jnvNiC42ld2pQW2KRI+pAG243L+iATvqzy3X6+NH1obz2itRKDZZ8VVhN3wjwYax/VBGCcXzgTqQ==

abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
Expand Down Expand Up @@ -85,6 +90,11 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"

any-promise@^1.0.0, any-promise@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=

anymatch@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
Expand Down Expand Up @@ -771,6 +781,13 @@ define-property@^2.0.2:
is-descriptor "^1.0.2"
isobject "^3.0.1"

definitelytyped-header-parser@Microsoft/definitelytyped-header-parser#production:
version "0.0.0"
resolved "https://codeload.github.com/Microsoft/definitelytyped-header-parser/tar.gz/6ff181ecd781706f200f8a780b0133a85fd0a69f"
dependencies:
"@types/parsimmon" "^1.3.0"
parsimmon "^1.2.0"

delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
Expand Down Expand Up @@ -810,6 +827,17 @@ domexception@^1.0.0:
dependencies:
webidl-conversions "^4.0.2"

dtslint@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/dtslint/-/dtslint-0.3.0.tgz#918e664a6f7e1f54ba22088daa2bc6e64a6001c1"
integrity sha512-3oWL8MD+2nKaxmNzrt8EAissP63hNSJ4OLr/itvNnPdAAl+7vxnjQ8p2Zdk0MNgdenqwk7GcaUDz7fQHaPgCyA==
dependencies:
definitelytyped-header-parser Microsoft/definitelytyped-header-parser#production
fs-promise "^2.0.0"
strip-json-comments "^2.0.1"
tslint "^5.9.1"
typescript next

duplexer@^0.1.1, duplexer@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
Expand Down Expand Up @@ -1112,12 +1140,30 @@ [email protected]:
jsonfile "^4.0.0"
universalify "^0.1.0"

fs-extra@^2.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35"
integrity sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=
dependencies:
graceful-fs "^4.1.2"
jsonfile "^2.1.0"

fs-minipass@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
dependencies:
minipass "^2.2.1"

fs-promise@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/fs-promise/-/fs-promise-2.0.3.tgz#f64e4f854bcf689aa8bddcba268916db3db46854"
integrity sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=
dependencies:
any-promise "^1.3.0"
fs-extra "^2.0.0"
mz "^2.6.0"
thenify-all "^1.6.0"

fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
Expand Down Expand Up @@ -1983,6 +2029,13 @@ json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"

jsonfile@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
optionalDependencies:
graceful-fs "^4.1.6"

jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
Expand Down Expand Up @@ -2244,6 +2297,15 @@ [email protected]:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"

mz@^2.6.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
dependencies:
any-promise "^1.0.0"
object-assign "^4.0.1"
thenify-all "^1.0.0"

nan@^2.9.2:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
Expand Down Expand Up @@ -2383,7 +2445,7 @@ oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"

object-assign@^4.1.0:
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"

Expand Down Expand Up @@ -2518,6 +2580,11 @@ [email protected]:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"

parsimmon@^1.2.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/parsimmon/-/parsimmon-1.12.0.tgz#886a442fb30b5fc3c8e7c4994050f5cdcfe0ea90"
integrity sha512-uC/BjuSfb4jfaWajKCp1mVncXXq+V1twbcYChbTxN3GM7fn+8XoHwUdvUz+PTaFtDSCRQxU8+Rnh+iMhAkVwdw==

pascalcase@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
Expand Down Expand Up @@ -3158,7 +3225,7 @@ strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"

strip-json-comments@~2.0.1:
strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"

Expand Down Expand Up @@ -3210,6 +3277,20 @@ test-exclude@^4.2.1:
read-pkg-up "^1.0.1"
require-main-filename "^1.0.1"

thenify-all@^1.0.0, thenify-all@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
dependencies:
thenify ">= 3.1.0 < 4"

"thenify@>= 3.1.0 < 4":
version "3.3.0"
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
dependencies:
any-promise "^1.0.0"

throat@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
Expand Down Expand Up @@ -3343,6 +3424,24 @@ tslint@^5.10.0:
tslib "^1.8.0"
tsutils "^2.12.1"

tslint@^5.9.1:
version "5.11.0"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed"
integrity sha1-mPMMAurjzecAYgHkwzywi0hYHu0=
dependencies:
babel-code-frame "^6.22.0"
builtin-modules "^1.1.1"
chalk "^2.3.0"
commander "^2.12.1"
diff "^3.2.0"
glob "^7.1.1"
js-yaml "^3.7.0"
minimatch "^3.0.4"
resolve "^1.3.2"
semver "^5.3.0"
tslib "^1.8.0"
tsutils "^2.27.2"

tsutils@^1.4.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-1.9.1.tgz#b9f9ab44e55af9681831d5f28d0aeeaf5c750cb0"
Expand All @@ -3353,6 +3452,13 @@ tsutils@^2.12.1:
dependencies:
tslib "^1.8.1"

tsutils@^2.27.2:
version "2.29.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
dependencies:
tslib "^1.8.1"

tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
Expand All @@ -3369,9 +3475,15 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"

typescript@next:
version "3.2.0-dev.20181116"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.2.0-dev.20181116.tgz#0a405b3385d6f180df78bf557167c0a608b5a501"
integrity sha512-+UUHAGhfccJe1ZnHbqp0uixDjT/yMguznOvF1p+16ytQPJaFo2MfIt6on4PZlgl7VhdxtENSfzl44xxjWsfj8Q==

typescript@~2.9.1:
version "2.9.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
integrity sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==

uglify-js@^2.6:
version "2.8.29"
Expand Down

0 comments on commit 4292a95

Please sign in to comment.