I had a similar problem that I had a giant list of properties that I wanted to have both an interface, and an object out of it.
NOTE: I didn't want to write (type with keyboard) the properties twice! Just DRY.
One thing to note here is, interfaces are enforced types at compile-time, while objects are mostly run-time. (Source)
As @derek mentioned in another answer, the common denominator of interface and object can be a class that serves both a type and a value.
So, TL;DR, the following piece of code should satisfy the needs:
class MyTableClass {
// list the propeties here, ONLY WRITTEN ONCE
id = "";
title = "";
isDeleted = false;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This is the pure interface version, to be used/exported
interface IMyTable extends MyTableClass { };
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Props type as an array, to be exported
type MyTablePropsArray = Array<keyof IMyTable>;
// Props array itself!
const propsArray: MyTablePropsArray =
Object.keys(new MyTableClass()) as MyTablePropsArray;
console.log(propsArray); // prints out ["id", "title", "isDeleted"]
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Example of creating a pure instance as an object
const tableInstance: MyTableClass = { // works properly!
id: "3",
title: "hi",
isDeleted: false,
};
(Here is the above code in Typescript Playground to play more)
PS. If you don't want to assign initial values to the properties in the class, and stay with the type, you can do the constructor trick:
class MyTableClass {
// list the propeties here, ONLY WRITTEN ONCE
constructor(
readonly id?: string,
readonly title?: string,
readonly isDeleted?: boolean,
) {}
}
console.log(Object.keys(new MyTableClass())); // prints out ["id", "title", "isDeleted"]