1.36.0 • Published 3 days ago

ts-roids v1.36.0

Weekly downloads
-
License
GPL-3.0-only
Repository
github
Last release
3 days ago

ts-roids

120+ types and decorators to bullet proof TypeScript even more.

tests @latest npm downloads bundle size

Types

Decorators

Basic Usage

Finalize and freeze objects

import type { Optional, NewType, MaybeUndefined } from 'ts-roids';
import { Final, Frozen } from 'ts-roids';

type Bar = NewType<'Bar', string>;
type Baz = NewType<'Baz', string>;
type Secret = NewType<'Secret', string>;

abstract class BaseFoo<T> {
  abstract requestFoo(secret: Secret, baz: Baz): Optional<T>;
}

@Final
@Frozen
class Foo<T> extends BaseFoo<T> {
  readonly foo: T;
  bar: Optional<Bar>;

  constructor(foo: T, bar?: MaybeUndefined<Bar>) {
    super();
    this.foo = foo;
    this.bar = bar ?? null;
  }


  requestFoo(secret: Secret, baz: Baz): Optional<T> {
    // A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value
    if (
      secret.concat().toLowerCase() === '123' &&
      baz.concat().toLowerCase() === 'baz' &&
      this.bar !== null
    ) {
      return this.foo;
    }

    return null; // So you have to explicitly return null here.
  }
}

class SubFoo extends Foo<string> {
  constructor(foo: string) {
    super(foo);
  }
}

// No problem with instantiation
const foo = new Foo<string>('foo');

// Since the object is final:

// The line below will cause a TypeError: Cannot inherit from the final class Foo
const _ = new SubFoo('subFoo');

// Since the object is frozen:

// The line below will cause a TypeError: Cannot add property 'requestFoo', object is not extensible
foo.requestFoo = () => {
  return 'not foo';
};

// The line below will cause a TypeError: Cannot assign to read only property 'bar'
foo.bar = 'not bar' as Bar;

The TypeScript team has not yet introduced a built-in final modifier yet, check this, this and many other requests. Although they introduced override in v4.3 .

Decorators like @Final provide a limited way to emulate final behavior, these are merely band-aids for now, until TS officially supports a true final modifier.

You can also seal an object btw.

@Sealed
class Person {
  constructor(name: string, age?: number) {}
}

const john = new Person('John', 30);

// Existing properties can still be modified
john.age = 31; // No Errors

// Existing properties cannot be re-configured nor deleted

(john as any).email = 'john@doe.com'; // TypeError: Cannot add property email,
// object is not extensible

delete john.age; // TypeError: Cannot delete property 'age' 

Changelog

See releases.

License

GPL-3

1.36.0

3 days ago

1.35.0

5 days ago

1.34.0

10 days ago

1.32.0

12 days ago

1.33.0

12 days ago

1.31.0

12 days ago

1.29.0

14 days ago

1.27.0

14 days ago

1.28.0

14 days ago

1.27.1

14 days ago

1.30.0

14 days ago

1.25.0

15 days ago

1.26.0

15 days ago

1.23.0

16 days ago

1.24.0

16 days ago

1.14.0

19 days ago

1.13.0

19 days ago

1.17.0

19 days ago

1.16.0

19 days ago

1.21.0

18 days ago

1.12.0

20 days ago

1.11.0

20 days ago

1.10.0

20 days ago

1.9.0

20 days ago