Skip to content

Commit

Permalink
Merge pull request #88 from zkulbeda/main
Browse files Browse the repository at this point in the history
Allow multiple brands and add Unbranded utility
  • Loading branch information
fabian-hiller authored Sep 17, 2023
2 parents 2af5dd3 + 6dcab51 commit ae97a42
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 5 deletions.
28 changes: 26 additions & 2 deletions library/src/methods/brand/brand.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, expectTypeOf, test } from 'vitest';
import { object, string } from '../../schemas/index.ts';
import { parse } from '../parse/index.ts';
import type { Output } from '../../types.ts';
import { parse } from '../parse/index.ts';
import { brand, type Brand } from './brand.ts';

describe('brand', () => {
Expand Down Expand Up @@ -31,9 +31,33 @@ describe('brand', () => {

test('should allow multiple branding', () => {
const branded1 = brand(string(), '1');
type Branded1 = Output<typeof branded1>;
const branded2 = brand(branded1, '2');
type Branded2 = Output<typeof branded2>;
expectTypeOf(branded1).not.toEqualTypeOf(branded2);

expectTypeOf<Branded1>().not.toBeNever();
expectTypeOf<Branded2>().not.toBeNever();

expectTypeOf<Branded2>().toMatchTypeOf<Branded1>();
expectTypeOf<Branded1>().not.toMatchTypeOf<Branded2>();

expectTypeOf<Branded2>().toEqualTypeOf<string & Brand<'1'> & Brand<'2'>>();
expectTypeOf<Branded2>().toMatchTypeOf<string & Brand<'1'>>();
});

test('should support brand hierarchy', () => {
const id = brand(string(), 'Id');
type BrandedId = Output<typeof id>;
const userId = brand(id, 'UserId');
type BrandedUserId = Output<typeof userId>;
const postId = brand(id, 'PostId');
type BrandedPostId = Output<typeof postId>;

expectTypeOf<BrandedId>().not.toBeNever();
expectTypeOf<BrandedUserId>().not.toBeNever();
expectTypeOf<BrandedPostId>().not.toBeNever();

expectTypeOf<BrandedUserId>().not.toMatchTypeOf<BrandedPostId>();
expectTypeOf<BrandedPostId>().not.toMatchTypeOf<BrandedUserId>();
});
});
4 changes: 2 additions & 2 deletions library/src/methods/brand/brand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import type {
Output,
} from '../../types.ts';

const symbol = Symbol('brand');
export const BrandSymbol = Symbol('brand');

/**
* Brand name type.
Expand All @@ -84,7 +84,7 @@ type BrandName = string | number | symbol;
* Brand type.
*/
export type Brand<TBrandName extends BrandName> = {
[symbol]: TBrandName;
[BrandSymbol]: { [TValue in TBrandName]: TValue };
};

export function brand<TSchema extends AnySchema, TBrandName extends BrandName>(
Expand Down
2 changes: 1 addition & 1 deletion library/src/methods/brand/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { brand } from './brand.ts';
export * from './brand.ts';

0 comments on commit ae97a42

Please sign in to comment.