Use let k: keyof T and a for-in loop to iterate objects when you know exactly what the keys will be or Object.entries to iterate over the keys and values of any object.
"Effective TypeScript" category
Prefer async/await to raw Promise when possible. They produce more concise, straightforward code and eliminate whole classes of errors.
Should you use type or interface? For complex types, you have no choice: you need to use a type alias. But what about the simpler object types that can be represented either way? To answer this question, you should consider consistency and augmentation. Are you working in a codebase that consistently uses interface? Then stick with interface. Does it use type? Then use type.
Consider applying type annotations to entire function expressions, rather than to their parameters and return type. If you're writing the same type signature repeatedly, factor out a function type.