Question: Expect function Parameter to be Key of Object with Dynamic Properties

Im making an application multi Language.
I want to build typing as strict and simpel as possible. My Code is the following:
//=== Inside my Hook: ===//
interface ITranslation {
   [key:string]:[string, string]
}

const useTranslator = (translations:ITranslation) => {
   const language = useLanguage() // just getting the language setting from another hook

   const translate = (key:keyof typeof translations) => {
      // mapping and returning the right translation
   }

   return translate;
}


//=== Inside the component: ===//
const translation:ITranlation = {
   "something in english": [ "something in german", "something in spanish" ],
   "anotherthing in english": ["anotherthing in german", "anotherthing in spanish"]
}

const translate = useTranslation(translation)

return(
   <Text>{translate("something in english")}</Text>
)


What i want to achieve:

When passing the translation Object, with Dynamic Keys to the Hook: useTranslation(translations), there should be a typecheck validating, that both languages are provided (any property has an Array with 2 Strings)

When using the translate function (inside the Text component) typescript should bring an error, if a key is not matching the Dynamic Keys inside the translations object. So this should throw an error: tranlate("not a key in object")


But i can't get it to work properly. I can either set the translations object as const, but then there is no typecheck when passing the object to the Hook.
Or i set it as shown above with translation:ITranslation but then there is no typechecking for the parameter in the ´translate´ function inside the component.
Is it possible to achive that? (If yes, how?)
Thanks in advance!


Answer:
This solution will work only for Typescript >= 4.9 since it uses the satisfies operator introduced in the 4.9.
Adding as const is the approach we will go with, and satisfies will allow us to type-check it.
const translation = {
  'something in english': ['something in german', 'something in spanish'],
  'anotherthing in english': ['anotherthing in german', 'anotherthing in spanish'],
} as const satisfies ITranslation;

Since we added as const the values in the ITranslation will be readonly [string, string], thus we have to update the ITranslation to the following:
interface ITranslation {
  [key: string]: readonly [string, string];
}

Next, we need to add a generic parameter to useTranslator so it works over the specific instance of ITranslation.  The same goes for the translate function. It should accept the generic parameter for the key of ITranslation and return the value for that specific key:
const useTranslator = <T extends ITranslation>(translations: T) => {
  const language = useLanguage(); // just getting the language setting from another hook

  const translate = <K extends keyof T>(key: K): T[K][number] => {
    // return retrieved value
  };

  return translate;
};

Since it is not asked in the question translate will return a union of the translations for the specific key, which is achieved by T[K][number]
Usage:
const Component = () => {
  const translate = useTranslator(translation);
  
  // "something in german" | "something in spanish"
  const case1 = translate('something in english');

  // "anotherthing in german" | "anotherthing in spanish"
  const case2 = translate( 'anotherthing in english');

  return null;
};

playground