I have an object which contains some predefined data for my application, which is stored in a const variable like this:
const data:{[key:string]:any} =Object.freeze({
some: 123,
long: {"a":"b"},
list: ["c"],
of: "",
arbitrary: null,
things: 1.2,
});
The keys of this object are known to the rest of the application. Consider this function which accesses the data object:
function doWork(k) {
if(!data.hasOwnProperty(k)) throw Error();
let value = data[k];
//...
}
This is called with strings like
doWork("things");
I would like to replace that runtime error for invalid keys with a Typescript compile-time check. I would like to be able to write
function doWork(k: keyof data) {
let value = data[k];
//...
}
But apparently the keyof
operator does not work that way. I get an error TS2304: Cannot find name 'data'.
My workaround: I can extract the keys of the object with something like this:
console.log("\""+Object.keys(data).join("\"|\"")+"\"");
Which I can then copy/paste and define as a type.
type data_key = "some"|"long"|"list"|"of"|"arbitrary"|"things"
export function doWork(k:data_key) {
let value = data[k];
//...
}
This feels like a silly hack and is quite inconvenient whenever I have to make a change, because I have to remember to put in this statement at the right place, run the program, and manually copy in the values back into the source code (or realistically, just type in the changes myself).
I am open to a better solution. Is there a language feature that provides the functionality I am looking for?