bolt-typegen
v1.2.4
Published
Generate TypeScript types from bolt security rules
Downloads
1
Readme
Bolt Type Generator :zap:
Generate TypesScript types from types declared in Bolt security rules.
This tool is useful if you use Bolt Compiler to author your security rules and you use typescript to write client code.
Consider some trivial security rules like:
path / is ToySchema {
read() { true }
}
type ToySchema {
stringChild: String;
nullableChild: Number | Null;
}
You can use this tool to generate types that reflect what the rules enforce:
export interface ToySchema {
stringChild: string;
nullableChild?: number;
}
Then you can use the emitted types to gain static typing of the values retrieved from firebase:
firebase.database().ref('/').once('value').then(snapshot => {
// 🎉
const x: ToySchema = snapshot.val();
})
Features
Preference for interface declarations with type declaration fallback
Bolt type definitions are translated to interface declarations whenever possible, and type declarations otherwise, such as when the type extends a native type or a Map (which are rendered as Record
s). It is possible to declare interfaces that extend Record
s, for example, when string
is passed as the key type argument, but we do not detect and emit interface declarations for those cases yet.
type NativeExtension extends String {}
type ObjectExtension {
child: String;
}
export type NativeExtension = String;
export interface ObjectExtension {
child: string;
}
Optional properties
In the Firebase realtime database, a field cannot hold null as a value. Assigning null to a field removes the field from the object entirely. Therefore, given a bolt type like:
type MyObject {
nonNullableField: String;
nullableField: String | Null;
}
a naive translation to nullableField: string | null;
is incorrect, and we make the property optional instead:
export interface MyObject {
nonNullableField: string;
nullableField?: string;
}
Fields in the realtime database also cannot hold an empty object as a value. When all the fields on an object are assigned null (are deleted), the field that held the object is also removed entirely. Consider the type:
type MyObject {
nullableField: String | null;
}
type MyOtherObject {
myObject: MyObject;
}
The field myObject
does not explicitly include Null
in a union like in the first example, but the field must still be optional because if nullableField
is set to null, the value would be an empty object, and the myObject
field is removed.
See the basic nullable, implicit nullability, and implicity nullability via type params tests for more cases and examples.
Usage
import { generateTypes } from 'bolt-typegen';
generateTypes('type Person { name: String }')
// => 'export interface Person { name: string; }'