Using Schemats, you can generate TypeScript interface definitions from (Postgres, MySQL) SQL database schema automatically.
Start with a database schema:
| Users | |
|---|---|
| id | SERIAL |
| username | VARCHAR |
| password | VARCHAR |
| last_logon | TIMESTAMP |
Automatically have the following TypesScript Interface generated
interface Users {
id: number;
username: string;
password: string;
last_logon: Date;
}For an overview on the motivation and rational behind this project, please take a look at Statically typed PostgreSQL queries in Typescript .
npm install -g schemats
schemats generate -c postgres://postgres@localhost/osm -t users -o osm.ts
schemats generate -c mysql://mysql@localhost/osm -t users -o osm.ts
The above commands will generate typescript interfaces for osm database
with table users. The resulting file is stored as osm.ts.
To generate all type definitions for all the tables within the schema 'public':
Note: MySQL does not have a default public schema, but should it have a schema named public, this will still work.
schemats generate -c postgres://postgres@localhost/osm -s public -o osm.ts
schemats generate -c mysql://mysql@localhost/osm -s public -o osm.ts
If neither the table parameter nor the schema parameter is provided, all tables in schema 'public' will be generated, so the command above is equivalent to:
schemats generate -c postgres://postgres@localhost/osm -o osm.ts
schemats generate -c mysql://mysql@localhost/osm -o osm.ts
Schemats supports reading configuration from a json config file (defaults to schemats.json). Instead of passing configuration via commandline parameter like done above, it is also possible to supply the configuration through a config file. The config file supports the same parameters as the commandline arguments.
For example, if a schemats.json exists in the current working directory with the following content:
{
"conn": "postgres://postgres@localhost/osm",
"table": ["users"]
}Running schemats generate here is equivalent to running schemats generate -c postgres://postgres@localhost/osm -t users -o osm.ts.
We can import osm.ts directly
// imports the _osm_ namespace from ./osm.ts
import * as osm from './osm'
// Now query with pg-promise and have a completely typed return value
let usersCreatedAfter2013: Array<osm.users>
= await db.query("SELECT * FROM users WHERE creation_time >= '2013-01-01'");
// We can decide to only get selected fields
let emailOfUsersCreatedAfter2013: Array<{
email: osm.users['email'],
creation_time: osm.users['creation_time']
}> = await db.query("SELECT (email, creation_time) FROM users WHERE creation_time >= '2013-01-01'");With generated type definition for our database schema, we can write code with autocompletion and static type checks.
Schemats exposes a few high-level functions for generating typescript definition from a database schema. They can be used by a build tool such as grunt and gulp.
typescriptOfTable (db, table, schema, options)
db - database connection string or database object. If you are calling the function multiple times in your script, use a database object.
table - database table you want to generate definitions for
schema - database schema
options - options object
import { typescriptOfTable, Options, getDatabase } from 'schemats'
import fs from 'fs'
//optional - defaults shown
const options = new Options({
camelCase: true,
writeHeader: true
})
typescriptOfTable('postgres://username:password@hostname/osm', 'users', 'public', options)
.then(types => fs.writeFile('osm.ts', types, (err) => { if (err) console.log(err) }))typescriptOfSchema (db, table, schema, options)
db - database connection string or database object. If you are calling the function multiple times in your script, use a database object.
table - array of database tables you want to generate definitions for
schema - database schema, defaults to default schema in the db
options - options object - just a plain object, not an instance of Options
import { typescriptOfSchema, getDatabase } from 'schemats'
//optional - defaults shown
const options = {
camelCase: true,
writeHeader: true
}
const schemas = ['osm', 'foo', 'bar']
/*
If you just passed in the connection string instead of getting a
connection like this you would get an error like
WARNING: Creating a duplicate database object for the same connection
and you may even get errors if you use all your configured connections on your db
*/
const database = getDatabase('postgres://username:password@hostname/dbname')
schemas.forEach(async (schema) => {
const types = await typescriptOfSchema(
database,
[], //this will generate types for all tables in the schema unless you put table names in here
schema
)
fs.writeFile(`types/${schema}.ts`, types, (err) => { if (err) console.log(err) })
})Version 1.0 deprecates generating schema typescript files with namespace.
Instead of generating schema typescript files with
schemats generate -c postgres://postgres@localhost/db -n yournamespace -o db.tsand import them with
import {yournamespace} from './db'It is now encouraged to generate without namespace
schemats generate -c postgres://postgres@localhost/db -o db.tsand import them with
import * as yournamespace from './db'
// or
import {table_a, table_b} from './db'As TypeScript's documentation describes, having a top level namespace is needless. This was discussed in #25.
Generating schema typescript files with namespace still works in v1.0, but it is discouraged and subjected to removal in the future.
Version 1.0 supports strict null-checking and reflects the NOT NULL constraint defined in PostgreSQL schema.

