From dc4154419fc9a5db8cade1d5f01914cf5874a3c7 Mon Sep 17 00:00:00 2001 From: Sonishi Izuka Date: Sat, 10 Apr 2021 21:20:37 +0900 Subject: [PATCH] feat(ts-type-util-is-readonly-array): create a new package (#28) * chore(ts-type-util-is-readonly-array): create a directory for the `@sounisi5011/ts-type-util-is-readonly-array` package * chore(./packages/ts-type-utils/): move tsconfig file with same settings into parent directory * feat(ts-type-util-is-readonly-array): create a new package * test(ts-type-util-is-readonly-array): add tests for using tsd * test(ts-type-util-is-readonly-array): fix type testing * test(ts-type-util-is-readonly-array): refactor the tests of type * test(ts-type-util-is-readonly-array): add tests of type * docs(ts-type-util-is-readonly-array): add `README.md` * docs(ts-type-util-is-readonly-array): fix the `description` field in the `package.json` file --- .../has-own-property/tsconfig.build.json | 12 +- .../has-own-property/tsconfig.json | 2 +- .../ts-type-utils/is-readonly-array/README.md | 57 ++++++++ .../is-readonly-array/index.test-d.ts | 127 ++++++++++++++++++ .../ts-type-utils/is-readonly-array/index.ts | 1 + .../is-readonly-array/package.json | 41 ++++++ .../is-readonly-array/tsconfig.build.json | 3 + .../is-readonly-array/tsconfig.json | 3 + packages/ts-type-utils/tsconfig.base.json | 3 + packages/ts-type-utils/tsconfig.build.json | 13 ++ packages/ts-type-utils/tsconfig.test.json | 9 ++ pnpm-lock.yaml | 5 + 12 files changed, 264 insertions(+), 12 deletions(-) create mode 100644 packages/ts-type-utils/is-readonly-array/README.md create mode 100644 packages/ts-type-utils/is-readonly-array/index.test-d.ts create mode 100644 packages/ts-type-utils/is-readonly-array/index.ts create mode 100644 packages/ts-type-utils/is-readonly-array/package.json create mode 100644 packages/ts-type-utils/is-readonly-array/tsconfig.build.json create mode 100644 packages/ts-type-utils/is-readonly-array/tsconfig.json create mode 100644 packages/ts-type-utils/tsconfig.base.json create mode 100644 packages/ts-type-utils/tsconfig.build.json create mode 100644 packages/ts-type-utils/tsconfig.test.json diff --git a/packages/ts-type-utils/has-own-property/tsconfig.build.json b/packages/ts-type-utils/has-own-property/tsconfig.build.json index 9a473ec33..87e817924 100644 --- a/packages/ts-type-utils/has-own-property/tsconfig.build.json +++ b/packages/ts-type-utils/has-own-property/tsconfig.build.json @@ -1,13 +1,3 @@ { - "extends": "./tsconfig.json", - "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - "declarationMap": false, - - /* Advanced Options */ - "emitDeclarationOnly": true - }, - "exclude": ["*.test-d.ts"] + "extends": "../tsconfig.build.json" } diff --git a/packages/ts-type-utils/has-own-property/tsconfig.json b/packages/ts-type-utils/has-own-property/tsconfig.json index d11d1cc1f..38ca0b13b 100644 --- a/packages/ts-type-utils/has-own-property/tsconfig.json +++ b/packages/ts-type-utils/has-own-property/tsconfig.json @@ -1,3 +1,3 @@ { - "extends": "../../../tsconfig.base.json" + "extends": "../tsconfig.test.json" } diff --git a/packages/ts-type-utils/is-readonly-array/README.md b/packages/ts-type-utils/is-readonly-array/README.md new file mode 100644 index 000000000..097859671 --- /dev/null +++ b/packages/ts-type-utils/is-readonly-array/README.md @@ -0,0 +1,57 @@ +# @sounisi5011/ts-type-util-is-readonly-array + +[![Go to the latest release page on npm](https://img.shields.io/npm/v/@sounisi5011/ts-type-util-is-readonly-array.svg)](https://www.npmjs.com/package/@sounisi5011/ts-type-util-is-readonly-array) + +Fix the type definition of [`Array.isArray()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) method to accept readonly arrays. + +## Installation + +```sh +npm install @sounisi5011/ts-type-util-is-readonly-array +``` + +```sh +yarn add @sounisi5011/ts-type-util-is-readonly-array +``` + +```sh +pnpm add @sounisi5011/ts-type-util-is-readonly-array +``` + +## Usage + +```ts +import { isReadonlyArray } from '@sounisi5011/ts-type-util-is-readonly-array'; + +const isArray = Array.isArray as isReadonlyArray; + +if (isArray(value)) { + // ... +} + +function fn(param: string | readonly string[]) { + if (isArray(param)) { + // ... + } else { + // ... + } +} +``` + +or + +```ts +import { isReadonlyArray } from '@sounisi5011/ts-type-util-is-readonly-array'; + +if ((Array.isArray as isReadonlyArray)(value)) { + // ... +} + +function fn(param: string | readonly string[]) { + if ((Array.isArray as isReadonlyArray)(param)) { + // ... + } else { + // ... + } +} +``` diff --git a/packages/ts-type-utils/is-readonly-array/index.test-d.ts b/packages/ts-type-utils/is-readonly-array/index.test-d.ts new file mode 100644 index 000000000..0bd030604 --- /dev/null +++ b/packages/ts-type-utils/is-readonly-array/index.test-d.ts @@ -0,0 +1,127 @@ +import { expectType } from 'tsd'; + +import type { isReadonlyArray } from '.'; + +const isArray = Array.isArray as isReadonlyArray; + +// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- // + +export function test1(param: string | readonly string[]): void { + if (isArray(param)) { + expectType(param); + } else { + expectType(param); + } + + if ((Array.isArray as isReadonlyArray)(param)) { + expectType(param); + } else { + expectType(param); + } +} + +export function test2(param: string | string[]): void { + if (isArray(param)) { + expectType(param); + } else { + expectType(param); + } + + if ((Array.isArray as isReadonlyArray)(param)) { + expectType(param); + } else { + expectType(param); + } +} + +export function test3(param: boolean | string[] | readonly number[]): void { + if (isArray(param)) { + expectType(param); + } else { + expectType(param); + } + + if ((Array.isArray as isReadonlyArray)(param)) { + expectType(param); + } else { + expectType(param); + } +} + +export function test4(param: unknown): void { + if (isArray(param)) { + expectType(param); + } else { + expectType(param); + } +} + +export function test5(param: T): void { + if (isArray(param)) { + expectType(param); + } else { + expectType(param); + } +} + +/* eslint-disable @typescript-eslint/ban-types */ +export function test6(param: {}): void { + if (isArray(param)) { + expectType(param); + } else { + expectType<{}>(param); + } + /* eslint-enable */ +} + +/* + * see https://github.com/orta/TypeScript/blob/c69b255bf69469838a3b755961471a2cdd63fea7/tests/cases/compiler/consistentUnionSubtypeReduction.ts + */ + +declare const a: readonly string[] | string; +declare const b: string[] | string; +declare const c: unknown; + +if (isArray(a)) { + expectType(a); +} else { + expectType(a); +} +expectType(a); + +if (isArray(b)) { + expectType(b); +} else { + expectType(b); +} +expectType(b); + +if (isArray(c)) { + expectType(c); +} + +export function f(_x: T): void { + /* eslint-disable @typescript-eslint/no-explicit-any */ + const a: readonly T[] | string = null as any; + const b: T[] | string = null as any; + const c: T = null as any; + /* eslint-enable */ + + if (isArray(a)) { + expectType(a); + } else { + expectType(a); + } + expectType(a); + + if (isArray(b)) { + expectType(b); + } else { + expectType(b); + } + expectType(b); + + if (isArray(c)) { + expectType(c); + } +} diff --git a/packages/ts-type-utils/is-readonly-array/index.ts b/packages/ts-type-utils/is-readonly-array/index.ts new file mode 100644 index 000000000..0ba44c626 --- /dev/null +++ b/packages/ts-type-utils/is-readonly-array/index.ts @@ -0,0 +1 @@ +export type isReadonlyArray = (arg: unknown) => arg is readonly unknown[]; diff --git a/packages/ts-type-utils/is-readonly-array/package.json b/packages/ts-type-utils/is-readonly-array/package.json new file mode 100644 index 000000000..3ae2ca86b --- /dev/null +++ b/packages/ts-type-utils/is-readonly-array/package.json @@ -0,0 +1,41 @@ +{ + "name": "@sounisi5011/ts-type-util-is-readonly-array", + "version": "0.0.0", + "description": "Fix the type definition of `Array.isArray()` method to accept readonly arrays", + "keywords": [ + "ReadonlyArray", + "array", + "isArray", + "isReadonlyArray", + "readonly", + "ts", + "types", + "typescript", + "util", + "utility" + ], + "homepage": "https://github.com/sounisi5011/npm-packages/tree/main/packages/ts-type-utils/is-readonly-array#readme", + "bugs": { + "url": "https://github.com/sounisi5011/npm-packages/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/sounisi5011/npm-packages.git", + "directory": "packages/ts-type-utils/is-readonly-array" + }, + "license": "MIT", + "author": "sounisi5011", + "types": "./index.d.ts", + "files": [ + "index.d.ts" + ], + "scripts": { + "build": "tsc -p ./tsconfig.build.json", + "lint:tsc": "tsc --noEmit", + "test": "run-s build test:tsd", + "test:tsd": "tsd" + }, + "devDependencies": { + "tsd": "0.14.0" + } +} diff --git a/packages/ts-type-utils/is-readonly-array/tsconfig.build.json b/packages/ts-type-utils/is-readonly-array/tsconfig.build.json new file mode 100644 index 000000000..87e817924 --- /dev/null +++ b/packages/ts-type-utils/is-readonly-array/tsconfig.build.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.build.json" +} diff --git a/packages/ts-type-utils/is-readonly-array/tsconfig.json b/packages/ts-type-utils/is-readonly-array/tsconfig.json new file mode 100644 index 000000000..38ca0b13b --- /dev/null +++ b/packages/ts-type-utils/is-readonly-array/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.test.json" +} diff --git a/packages/ts-type-utils/tsconfig.base.json b/packages/ts-type-utils/tsconfig.base.json new file mode 100644 index 000000000..9536a0f41 --- /dev/null +++ b/packages/ts-type-utils/tsconfig.base.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.base.json" +} diff --git a/packages/ts-type-utils/tsconfig.build.json b/packages/ts-type-utils/tsconfig.build.json new file mode 100644 index 000000000..eb60727e2 --- /dev/null +++ b/packages/ts-type-utils/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + "declarationMap": false, + + /* Advanced Options */ + "emitDeclarationOnly": true + }, + "exclude": ["*/*.test-d.ts"] +} diff --git a/packages/ts-type-utils/tsconfig.test.json b/packages/ts-type-utils/tsconfig.test.json new file mode 100644 index 000000000..8c8bc086a --- /dev/null +++ b/packages/ts-type-utils/tsconfig.test.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + "noEmit": true + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 301c82685..8e330549b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,11 @@ importers: tsd: 0.14.0 specifiers: tsd: 0.14.0 + packages/ts-type-utils/is-readonly-array: + devDependencies: + tsd: 0.14.0 + specifiers: + tsd: 0.14.0 lockfileVersion: 5.2 packages: /@actions/core/1.2.6: