Skip to content

Commit

Permalink
Function Type Unpackers (#24)
Browse files Browse the repository at this point in the history
* Update Dependencies - yarn.lock

* Implement ParamN & ParamTypes

for #22
  • Loading branch information
fbartho authored and pelotom committed Jul 10, 2018
1 parent cb8aef0 commit 433eee0
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 48 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ See: https://github.com/pelotom/type-zoo/pull/14#discussion_r183527882

---

### `Param#<T extends Function>` and `ParamTypes<T extends Function>`

These helpers extract the Parameter-types from Functions.

See: https://github.com/pelotom/type-zoo/issues/22

---

### `Pick#<T, K1 in keyof T, K2 in ...>`

Like `Pick<>` but for `#` of nested levels!
Expand Down
39 changes: 39 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,45 @@ export type NoInfer<T> = T & { [K in keyof T]: T[K] };
*/
export type Purify<T extends string> = { [P in T]: T; }[T];

/**
* Selects the type of the 0th parameter in a function-type
*/
export type Param0<Func> = Func extends (a: infer T, ...args: any[]) => any
? T
: never;
/**
* Selects the type of the 1st parameter in a function-type
*/
export type Param1<Func> = Func extends (a: any, b: infer T, ...args: any[]) => any
? T
: never;
/**
* Selects the type of the 2nd parameter in a function-type
*/
export type Param2<Func> = Func extends (a: any, b: any, c: infer T, ...args: any[]) => any
? T
: never;
/**
* Selects the type of the 3rd parameter in a function-type
*/
export type Param3<Func> = Func extends (a: any, b: any, c: any, d: infer T, ...args: any[]) => any
? T
: never;
/**
* Selects the types of all the parameters in a function-type.
* Warnings:
* - This is probably less performant if you're only looking up a single param! {@see Param0-Param# }
* - This omits rest parameters (...args:any[])
*/
export type ParamTypes<F extends Function> = // tslint:disable-line
F extends () => any ? {} :
F extends (p0: infer P0) => any ? [P0] :
F extends (p0: infer P0, p1: infer P1) => any ? [P0, P1] :
F extends (p0: infer P0, p1: infer P1, p2: infer P2) => any ? [P0, P1, P2] :
F extends (p0: infer P0, p1: infer P1, p2: infer P2, p3: infer P3) => any ? [P0, P1, P2, P3] :
// ... -- extend this at your own risk, this could be bad for compilation performance!
never;

/**
* Picks 2 levels deep into a nested object!
*
Expand Down
57 changes: 57 additions & 0 deletions types/param-n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Param0, Param1, Param2, Param3, ParamTypes } from 'type-zoo';

function a() { return; }
const b = () => { return; };

// $ExpectType {}
type A1 = Param0<typeof a>;
// $ExpectType {}
type B1 = Param0<typeof b>;
// $ExpectType {}
type A2 = ParamTypes<typeof a>;
// $ExpectType {}
type B2 = ParamTypes<typeof b>;

// $ExpectError
type A3 = A2[0];
// $ExpectError
type B3 = B2[0];

const c1 = (a: string) => { return; };
const c2 = (a: number, b: boolean) => { return; };
function c3(a: boolean[], b: object, c: any, d: "foo") { return; }
function c4(a: number, ...args: string[]) { return; }
function c5(a: boolean[], b: object, c: any, d: "foo", e: 1, ...args: any[]) { return; }

// $ExpectType string
type C1 = Param0<typeof c1>;
// $ExpectType {}
type C2 = Param1<typeof c1>;
// $ExpectType boolean
type C3 = Param1<typeof c2>;
// $ExpectType boolean[]
type C4 = Param0<typeof c3>;
// $ExpectType object
type C5 = Param1<typeof c3>;
// $ExpectType any
type C6 = Param2<typeof c3>;
// $ExpectType "foo"
type C7 = Param3<typeof c3>;
// $ExpectType [boolean[], object, any, "foo"]
type C8 = ParamTypes<typeof c3>;

// Var-args -- rest parameters!
// $ExpectType string
type C9 = Param1<typeof c4>;
// $ExpectType string
type C10 = Param2<typeof c4>;
// $ExpectType string
type C11 = Param3<typeof c4>;

// Currently this type-operator ignores rest parameters (...args:any[])
// $ExpectType [number]
type C12 = ParamTypes<typeof c4>;

// Currently this type-operator has a max limit of 4 parameter-types unpacked as a tuple
// $ExpectType never
type C13 = ParamTypes<typeof c5>;
96 changes: 48 additions & 48 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@


"@types/parsimmon@^1.3.0":
version "1.6.1"
resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.6.1.tgz#c5d849baf59820389d03564ec4b0bea5900e64cb"
version "1.10.0"
resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.0.tgz#ffb81cb023ff435a41d4710a29ab23c561dc9fdf"

ansi-regex@^2.0.0:
version "2.1.1"
Expand All @@ -14,9 +14,9 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"

ansi-styles@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
dependencies:
color-convert "^1.9.0"

Expand All @@ -25,8 +25,8 @@ any-promise@^1.0.0, any-promise@^1.3.0:
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"

argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
dependencies:
sprintf-js "~1.0.2"

Expand All @@ -43,8 +43,8 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"

brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
Expand All @@ -64,41 +64,41 @@ chalk@^1.1.3:
supports-color "^2.0.0"

chalk@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
dependencies:
ansi-styles "^3.1.0"
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"
supports-color "^5.3.0"

color-convert@^1.9.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed"
version "1.9.2"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147"
dependencies:
color-name "^1.1.1"
color-name "1.1.1"

color-name@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
[email protected]:
version "1.1.1"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689"

commander@^2.12.1:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
version "2.16.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50"

[email protected]:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"

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

diff@^3.2.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c"
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"

dtslint@^0.3.0:
version "0.3.0"
Expand Down Expand Up @@ -163,9 +163,9 @@ has-ansi@^2.0.0:
dependencies:
ansi-regex "^2.0.0"

has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"

inflight@^1.0.4:
version "1.0.6"
Expand All @@ -183,8 +183,8 @@ js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"

js-yaml@^3.7.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc"
version "3.12.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
Expand Down Expand Up @@ -220,8 +220,8 @@ once@^1.3.0:
wrappy "1"

parsimmon@^1.2.0:
version "1.6.4"
resolved "https://registry.yarnpkg.com/parsimmon/-/parsimmon-1.6.4.tgz#7ff16d52d58b9769d019b401848ee2c9bd94dd86"
version "1.11.1"
resolved "https://registry.yarnpkg.com/parsimmon/-/parsimmon-1.11.1.tgz#86493d7130636ffdcf748913b84f23916ec16f31"

path-is-absolute@^1.0.0:
version "1.0.1"
Expand All @@ -232,8 +232,8 @@ path-parse@^1.0.5:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"

resolve@^1.3.2:
version "1.5.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
version "1.8.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
dependencies:
path-parse "^1.0.5"

Expand All @@ -259,11 +259,11 @@ supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"

supports-color@^4.0.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b"
supports-color@^5.3.0:
version "5.4.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
dependencies:
has-flag "^2.0.0"
has-flag "^3.0.0"

thenify-all@^1.0.0, thenify-all@^1.6.0:
version "1.6.0"
Expand All @@ -278,12 +278,12 @@ thenify-all@^1.0.0, thenify-all@^1.6.0:
any-promise "^1.0.0"

tslib@^1.8.0, tslib@^1.8.1:
version "1.9.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"

tslint@^5.9.1:
version "5.9.1"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.9.1.tgz#1255f87a3ff57eb0b0e1f0e610a8b4748046c9ae"
version "5.10.0"
resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.10.0.tgz#11e26bccb88afa02dd0d9956cae3d4540b5f54c3"
dependencies:
babel-code-frame "^6.22.0"
builtin-modules "^1.1.1"
Expand All @@ -299,18 +299,18 @@ tslint@^5.9.1:
tsutils "^2.12.1"

tsutils@^2.12.1:
version "2.19.1"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.19.1.tgz#76d7ebdea9d7a7bf4a05f50ead3701b0168708d7"
version "2.27.2"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.27.2.tgz#60ba88a23d6f785ec4b89c6e8179cac9b431f1c7"
dependencies:
tslib "^1.8.1"

typescript@^2.8.1:
version "2.8.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.1.tgz#6160e4f8f195d5ba81d4876f9c0cc1fbc0820624"
version "2.9.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"

typescript@next:
version "2.8.0-dev.20180127"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.8.0-dev.20180127.tgz#289893b34fc86d6ad572b4cbf01e6df815e22fdf"
version "3.0.0-dev.20180710"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.0-dev.20180710.tgz#19a5ad2191ddc1f4d5cb29c2f20d37bb98613848"

wrappy@1:
version "1.0.2"
Expand Down

0 comments on commit 433eee0

Please sign in to comment.