From 892d60879b85931ce5c8378af3b100d1b4b73efc Mon Sep 17 00:00:00 2001 From: Dmitry Scheglov Date: Thu, 26 Sep 2024 16:44:08 +0200 Subject: [PATCH 1/2] [dsch] adding the type-hidden properties error to Ok and value to Err of type never --- examples/methods.ts | 4 ++-- package.json | 9 +++++---- src/Err.ts | 4 ++++ src/Ok.ts | 4 ++++ src/result.test.ts | 24 ++++++++++++++++++++++++ tsup.config.js | 5 +++-- 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/examples/methods.ts b/examples/methods.ts index 6e40234..d8ccd1f 100644 --- a/examples/methods.ts +++ b/examples/methods.ts @@ -119,8 +119,8 @@ import { Result, ok, err } from 'okerr-ts/base'; } { - const okResult: Result = ok(42); - const errResult: Result = err('ERR_NOT_FOUND'); + const okResult = ok(42) as Result; + const errResult = err('ERR_NOT_FOUND') as Result; const value = okResult.unpack(); // 42 const error = errResult.unpack(); // 'ERR_NOT_FOUND' diff --git a/package.json b/package.json index eda3048..acaf2a8 100644 --- a/package.json +++ b/package.json @@ -30,18 +30,19 @@ }, "license": "MIT", "devDependencies": { - "@type-challenges/utils": "^0.1.1", - "@types/node": "^20.10.5", "@eslint/js": "^9.7.0", + "@type-challenges/utils": "^0.1.1", "@types/eslint": "^9.6.0", + "@types/node": "^20.10.5", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", - "typescript-eslint": "^7.17.0", "jest": "^29.7.0", + "terser": "^5.33.0", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", "tsup": "^8.3.0", - "typescript": "^5.6.2" + "typescript": "^5.6.2", + "typescript-eslint": "^7.17.0" }, "exports": { ".": { diff --git a/src/Err.ts b/src/Err.ts index 0e10fa3..8ee6605 100644 --- a/src/Err.ts +++ b/src/Err.ts @@ -13,6 +13,10 @@ export class ErrImpl implements Err { return true; } + get value(): never { + throw new TypeError('Result is not an Ok', { cause: this }); + } + map(): Result { return this; } diff --git a/src/Ok.ts b/src/Ok.ts index f8279aa..7365289 100644 --- a/src/Ok.ts +++ b/src/Ok.ts @@ -14,6 +14,10 @@ export class OkImpl implements Ok { return false; } + get error(): never { + throw new TypeError('Result is not an Err', { cause: this }); + } + map(fn: (value: T) => S): Result { return new OkImpl(fn(this.value)); } diff --git a/src/result.test.ts b/src/result.test.ts index e0021c3..1cddb7c 100644 --- a/src/result.test.ts +++ b/src/result.test.ts @@ -121,6 +121,30 @@ describe('Result', () => { }); }); + describe('Ok.value', () => { + it('returns the value for an Ok result', () => { + expect(ok('foo').value).toBe('foo'); + }); + + it('throws a TypeError for an Err result', () => { + expect(() => (err('foo') as any).value).toThrowError( + new TypeError('Result is not an Ok', { cause: err('foo') }), + ); + }); + }); + + describe('Err.error', () => { + it('returns the error for an Err result', () => { + expect(err('foo').error).toBe('foo'); + }); + + it('throws a TypeError for an Ok result', () => { + expect(() => (ok('foo') as any).error).toThrowError( + new TypeError('Result is not an Err', { cause: ok('foo') }), + ); + }); + }); + describe('isErr', () => { it('should return true for an Err result', () => { expect(Guards.isErr(err('foo'))).toBe(true); diff --git a/tsup.config.js b/tsup.config.js index 143fc21..e89bfc5 100644 --- a/tsup.config.js +++ b/tsup.config.js @@ -14,7 +14,7 @@ const entries = [ ]; export default defineConfig( - entries.map(([entry, globalName]) => ({ + entries.map(([entry, globalName, options]) => ({ entry, globalName, format: ['iife'], @@ -24,9 +24,10 @@ export default defineConfig( }; }, dts: true, - minify: false, + minify: 'terser', splitting: false, sourcemap: true, outDir: 'dist', + ...options, })), ); From b2349eb9a49325a3a4d720fe42a820fa5ded3ae0 Mon Sep 17 00:00:00 2001 From: Dmitry Scheglov Date: Thu, 26 Sep 2024 16:56:37 +0200 Subject: [PATCH 2/2] [dsch] improvement for the error messages on ok.error and err.value --- src/Err.ts | 4 +++- src/Ok.ts | 4 +++- src/result.test.ts | 8 ++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Err.ts b/src/Err.ts index 8ee6605..3664654 100644 --- a/src/Err.ts +++ b/src/Err.ts @@ -14,7 +14,9 @@ export class ErrImpl implements Err { } get value(): never { - throw new TypeError('Result is not an Ok', { cause: this }); + throw new TypeError('Cannot access `value` on an Err instance.', { + cause: this, + }); } map(): Result { diff --git a/src/Ok.ts b/src/Ok.ts index 7365289..114514d 100644 --- a/src/Ok.ts +++ b/src/Ok.ts @@ -15,7 +15,9 @@ export class OkImpl implements Ok { } get error(): never { - throw new TypeError('Result is not an Err', { cause: this }); + throw new TypeError('Cannot access `error` on an Ok instance.', { + cause: this, + }); } map(fn: (value: T) => S): Result { diff --git a/src/result.test.ts b/src/result.test.ts index 1cddb7c..62cb02a 100644 --- a/src/result.test.ts +++ b/src/result.test.ts @@ -128,7 +128,9 @@ describe('Result', () => { it('throws a TypeError for an Err result', () => { expect(() => (err('foo') as any).value).toThrowError( - new TypeError('Result is not an Ok', { cause: err('foo') }), + new TypeError('Cannot access `value` on an Err instance.', { + cause: err('foo'), + }), ); }); }); @@ -140,7 +142,9 @@ describe('Result', () => { it('throws a TypeError for an Ok result', () => { expect(() => (ok('foo') as any).error).toThrowError( - new TypeError('Result is not an Err', { cause: ok('foo') }), + new TypeError('Cannot access `error` on an Ok instance.', { + cause: ok('foo'), + }), ); }); });