npm package: @nik-kita/typeorm-single-table-inheritance-decorators
Description: > _This is amateur library. Use it on your own risk_
Author: https://github.com/nik-kita nik.moiseienko@gmail.com
Latest version: 1.0.5

# About
> _This is amateur library. Use it on your own risk_

[STI or Single Table Inheritance](https://orkhan.gitbook.io/typeorm/docs/entity-inheritance#single-table-inheritance) is the cool feature in Typeorm that
allow you to define many abstractions with common properties etc. under the one table.

It is absolutely your choose are you need this feature and so on...
But if you want to use it, you may meet some problems with difference behavior
if it was not inherited child table-abstractions but real tables.

The common example is `NOT NULL` constraint. Because only one child has some property
other child will always have `NULL` for it. So how define this constraint particularly
for special child?

One of the solutions is to use `@Check` decorator with custom constraint logic.
For example in our case it should be something like:
```ts
@Column()
@Check("type = 'OurChildType' AND onlyInThisChildProp IS NOT NULL")
onlyInThisChildProp: string;
```

But you see that there are a lot of manual code and raw sql etc.
So this is what this package do. It simply encapsulate these all for you.

Full example of usage, copied from test's fixtures:
```ts
/* eslint-disable max-classes-per-file */
import {
    ChildEntity, Column, Entity, PrimaryGeneratedColumn, TableInheritance,
} from 'typeorm';
import { NotNullForChildTypes } from '@nik-kita/typeorm-single-table-inheritance-decorators/with-snake-strategy';

export const stiTableName = 'sti_family' as const;

// eslint-disable-next-line no-shadow
export enum TestStiChildEnum {
SON = 'Son',
DAUGHTER = 'Daughter',
BROTHER = 'Brother',
SISTER = 'Sister',
}

@TableInheritance({
    column: {
        name: 'type',
        type: 'enum',
        enum: [TestStiChildEnum.SON, TestStiChildEnum.DAUGHTER, TestStiChildEnum.BROTHER, TestStiChildEnum.SISTER],
    },
})
@Entity(stiTableName)
export abstract class TestStiParent {
@PrimaryGeneratedColumn('uuid')
id!: string;

@Column({
    nullable: true,
})
common?: string;

@Column({
    nullable: true,
})
@NotNullForChildTypes([TestStiChildEnum.BROTHER, TestStiChildEnum.SISTER])
car?: string;
}

@ChildEntity(TestStiChildEnum.BROTHER)
export class TestStiBrother extends TestStiParent {
}

@ChildEntity(TestStiChildEnum.SISTER)
export class TestStiSister extends TestStiParent {
}

@ChildEntity(TestStiChildEnum.SON)
export class TestStiSon extends TestStiParent {
@Column({
    nullable: true,
})
@NotNullForChildTypes([TestStiChildEnum.SON])
lego?: string;
}

@ChildEntity(TestStiChildEnum.DAUGHTER)
export class TestStiDaughter extends TestStiParent {
@Column()
barby?: string;
}
```
---

## Bla bla bla...
* You see that the same functional is exists in many variants:
  * for default (raw) naming, when your class's property `firstName` will stored in database as `firstname` of you may be implicitly define class's name in sql convention like `first_name`...
  * for "snake" naming strategy getted from [this package](https://www.npmjs.com/package/typeorm-naming-strategies)