{"id":16497830,"url":"https://github.com/nshen/narrowing","last_synced_at":"2025-03-16T18:32:15.049Z","repository":{"id":38241894,"uuid":"351391377","full_name":"nshen/narrowing","owner":"nshen","description":"🤖 TypeScript tiny narrowing helpers you better use.","archived":false,"fork":false,"pushed_at":"2024-03-11T18:09:53.000Z","size":187,"stargazers_count":28,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-06T12:53:09.331Z","etag":null,"topics":["front-end","narrowing","react","typeguard","typescript","vue"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nshen.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-25T10:14:10.000Z","updated_at":"2024-05-06T14:40:55.000Z","dependencies_parsed_at":"2024-06-18T20:03:37.136Z","dependency_job_id":null,"html_url":"https://github.com/nshen/narrowing","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nshen%2Fnarrowing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nshen%2Fnarrowing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nshen%2Fnarrowing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nshen%2Fnarrowing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nshen","download_url":"https://codeload.github.com/nshen/narrowing/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243826783,"owners_count":20354220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["front-end","narrowing","react","typeguard","typescript","vue"],"created_at":"2024-10-11T14:45:46.592Z","updated_at":"2025-03-16T18:32:10.037Z","avatar_url":"https://github.com/nshen.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🤖 Narrowing\n\n[![npm](https://img.shields.io/npm/v/narrowing.svg)](https://www.npmjs.com/package/narrowing)\n[![npm](https://img.shields.io/npm/dt/narrowing)](https://www.npmjs.com/package/narrowing)\n\nTypeScript tiny [narrowing](https://www.typescriptlang.org/docs/handbook/2/narrowing.html) helpers you better use.\n\n## Install\n\n```bash\nnpm i narrowing  # yarn add narrowing\n```\n\n## Usage\n\n```typescript\nlet a: unknown;\n\nif (isXXX(a)) {\n  // TypeScript know your type here!\n}\n```\n\n## Functions\n\nBasic:\n\n- isString\n- isNumber\n- isBigInt\n- isBoolean\n- isSymbol\n- isUndefined\n- isNull\n- isNil\n- isFunction\n- isInstance\n- isArray\n- isObject\n\nAdvanced:\n\nThese functions help you make advanced type guards.\n\n- [has](#has)\n- [kind](#kind)\n- [literal](#literal)\n- [schema](#schema) (💪 `cool`)\n- [every](#every) (💪 `cool`)\n\n### basic examples\n\n```typescript\nimport {\n  isArray,\n  isBigInt,\n  isBoolean,\n  isFunction,\n  isInstance,\n  isNil,\n  isNull,\n  isNumber,\n  isObject,\n  isString,\n  isSymbol,\n  isUndefined\n} from 'narrowing';\n\nlet a: unknown;\n\nif (isString(a)) a.toLocaleLowerCase();\nif (isNumber(a)) a.toFixed();\nif (isBigInt(a)) a.toString();\nif (isBoolean(a)) a.valueOf();\nif (isSymbol(a)) a.toString();\nif (isUndefined(a)) {\n  a; // undefined\n}\nif (isNull(a)) {\n  a; // null\n}\nif (isNil(a)) {\n  a; // null | undefined\n}\n\nfunction testFunc(a: string, b: number): boolean {\n  return true;\n}\n\nif (isFunction\u003ctypeof testFunc\u003e(a)) {\n  a('11', 1); // no error\n}\n\nif (isInstance(a, Date)) {\n  a.getFullYear();\n}\n\nclass TestClass {\n  m() {}\n}\n\nif (isInstance(a, TestClass)) {\n  a.m();\n}\n\nif (isArray\u003cstring\u003e(a)) {\n  a[0].trim();\n}\n\nlet b: TestClass | undefined | null;\n// b.m(); // Error: Object is possibly 'null' or 'undefined'.ts(2533)\nif (!isNil(b)) {\n  b.m(); // no Error any more\n}\n\nif (isObject(a)) {\n  //   let a: {\n  //     [key: string]: unknown;\n  //   };\n  a;\n}\n```\n\n### `has()`\n\nCheck if a type has a property\n\n[TypeScript Handbook / Using type predicates](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates)\n\n```typescript\ntype Bird = { fly: () =\u003e {} };\ntype Cat = { run: () =\u003e {}; meow: () =\u003e {} };\ntype Dog = { run: () =\u003e {} };\n\nlet pet = {} as any;\n\n// save these type guards somewhere and reuse them\nconst isBird = has\u003cBird\u003e('fly');\nconst isDogOrCat = has\u003cDog | Cat\u003e('run');\nconst isCat = has\u003cCat\u003e('run', 'meow');\n\nif (isBird(pet)) {\n  pet.fly(); // Bird\n}\n\nif (isDogOrCat(pet)) {\n  pet.run(); // Dog | Cat\n}\n\nif (isCat(pet)) {\n  pet.meow(); // Cat\n}\n```\n\n### `kind()`\n\n[TypeScript handbook / Discriminated unions](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions)\n\n```typescript\ninterface Square {\n  kind: 'square';\n  size: number;\n}\ninterface Rectangle {\n  kind: 'rectangle';\n  width: number;\n  height: number;\n}\ninterface Circle {\n  kind: 'circle';\n  radius: number;\n}\n\nconst isSquare = kind\u003cSquare\u003e('square');\nconst isRectangle = kind\u003cRectangle\u003e('circle');\nconst isCircle = kind\u003cCircle\u003e('circle');\n\nlet s = {} as any;\n\nif (isSquare(s)) {\n  console.log(s.size);\n}\n\nif (isRectangle(s)) {\n  console.log(s.height);\n}\n\nif (isCircle(s)) {\n  console.log(s.radius);\n}\n```\n\n### `literal()`\n\n```ts\nconst is404 = literal(404);\nlet code = 200;\nif (is404(code)) {\n  // code's type should be 404 , not number\n  // let code: 404\n  code;\n}\n```\n\nthis is useful when you see `schema()`\n\n### `schema()`\n\nBasic schema validation\n\n```ts\nlet message: unknown = {\n  code: 200,\n  msg: 'success',\n  records: [\n    { id: 1, name: 'aaa' },\n    { id: 2, name: 'bbb' },\n    { id: 3, name: 'ccc' }\n  ]\n};\n\nconst isSuccess = schema({\n  code: literal(200),\n  msg: isString,\n  records: isArray\n});\n\nif (isSuccess(message)) {\n  // let message: {\n  //     code: 200;\n  //     msg: string;\n  //     records: unknown[];\n  // }\n  message;\n}\n```\n\nschema supports a type argument for associating a schema with an existing type\n\n```ts\ninterface TestInterface {\n  id: number;\n  name: string;\n}\n\nconst isTestInterface = schema\u003cTestInterface\u003e({\n  id: isNumber,\n  name: isString\n});\n\nif (isTestInterface(message)) {\n  // let message: TestInterface\n  message;\n}\n```\n\n### `every()`\n\nRuntime array type validation. Checks each element of an array.\n\n```ts\nlet arr: unknown[] = [1, 2, 3];\nif (every(isNumber)(arr)) {\n  let typeCheck: number[] = arr;\n}\n```\n\nWorks with any narrowing validator, including schemas.\n\n```ts\ninterface TestInterface {\n  id: number;\n  name: string;\n}\n\nconst isTestInterface = schema\u003cTestInterface\u003e({\n  id: isNumber,\n  name: isString\n});\n\nlet arr: unknown[] = [{ id: 1, name: 'aaa' }];\n\nif (every(isTestInterface)(arr)) {\n  let typeCheck: TestInterface[] = arr;\n}\n```\n\n## Version\n\n- 1.1.0\n  - add `has()`\n- 1.1.1\n  - `has()` accept multiple params\n- 1.2.1\n  - add `kind()`\n- 1.3.0\n  - add `isObject()`, `isValidObject()`\n- 1.4.0\n  - replace ~~`isValidObject()`~~ with `schema()`\n  - add `literal()`\n- 1.5.0\n  - add `every()`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnshen%2Fnarrowing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnshen%2Fnarrowing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnshen%2Fnarrowing/lists"}