Here is my code
async getAll(): Promise {
return await dbQuery(); // dbQuery returns User[]
}
class User {
id: number;
na
Unfortunately this isn't currently possible in Typescript, and somewhat contradicts the shape nature of TS type checking.
Answers in this thread that relay on the generic NoExtraProperties are very elegant, but unfortunately they are unreliable, and can result in difficult to detect bugs.
I'll demonstrate with GregL's answer.
// From GregL's answer
type Impossible = {
[P in K]: never;
};
type NoExtraProperties = U & Impossible>;
interface Animal {
name: string;
noise: string;
}
function thisWorks(animal: T & Impossible>): void {
console.log(`The noise that ${animal.name.toLowerCase()}s make is ${animal.noise}.`);
}
function thisIsAsGoodAsICanGetIt(animal: NoExtraProperties): void {
console.log(`The noise that ${animal.name.toLowerCase()}s make is ${animal.noise}.`);
}
const wrong2 = {
name: 'Rat',
noise: 'squeak',
idealScenarios: ['labs', 'storehouses'],
invalid: true,
};
thisWorks(wrong2); // yay, an error!
thisIsAsGoodAsICanGetIt(wrong2); // yay, an error!
This works if at the time of passing an object to thisWorks/thisIsAsGoodAsICanGet TS recognizes that the object has extra properties. But in TS if it's not an object literal, a value can always have extra properties:
const fun = (animal:Animal) =>{
thisWorks(animal) // No Error
thisIsAsGoodAsICanGetIt(animal) // No Error
}
fun(wrong2) // No Error
So, inside thisWorks/thisIsAsGoodAsICanGetIt you can't trust that the animal param doesn't have extra properties.
Simply use pick (Lodash, Ramda, Underscore).
interface Narrow {
a: "alpha"
}
interface Wide extends Narrow{
b: "beta"
}
const fun = (obj: Narrow) => {
const narrowKeys = ["a"]
const narrow = pick(obj, narrowKeys)
// Even if obj has extra properties, we know for sure that narrow doesn't
...
}