In C/C++, it is possible to write something like:
// version.h
extern const char *branch;
extern const char *hash;
extern const char *status;
extern const char *timestamp;
// version.c (autogenerated)
const char *branch = "dev";
const char *hash = "deadbeef";
const char *status = "dirty";
const char *timestamp = "1970-01-01T00:00:00.000Z";
// main.c
#include <stdio.h>
#include "version.h"
int main(void) {
printf("Build: %s-%s-%s %s\n", branch, hash, status, timestamp);
}
This way, after a fresh git clone
, the editor will not complain about the lack of variables, since version.h
always exists and “promises” the variables will exist when requested at compile/runtime. Importantly, the autogenerated version.c
and handwritten version.h
are guaranteed not to drift apart, since such a drift will cause compilation to fail.
The “equivalent” for .h
files in TypeScript is .d.ts
, which also “promises” things will exist at runtime.
// version.d.ts
export declare const branch: string;
export declare const hash: string;
export declare const status: "dirty" | "clean";
export declare const timestamp: Date;
// version.ts
export const branch = "dev";
export const hash = "deadbeef";
export const status = "dirty";
export const timestamp = new Date(0);
// index.ts
import { branch, hash, status, timestamp } from "./version.js";
console.log(`Build: ${branch}-${hash}-${status} ${timestamp.toISOString()}`);
However, unlike in C/C++, TypeScript does not check that a corresponding concrete implementation exists in some .ts
file, since it is possible to hook up with some other JS library at runtime, which does not go through TSC. Thus, such a check will need to be done manually, e.g., using the TS Compiler API. Which feels like an excessive amount of effort for what I’m actually trying to achieve. Or is it?
Stepping back a bit, my goal is simply to avoid requiring the autogeneration to be run after a fresh checkout and only when actually building, while still statically guaranteeing the handwritten “promises” and the autogenerated files will never go out of sync. Is there some other way to achieve this?