@titian is correct that typescript interfaces/types don't exist at runtime, but the executable code DOES exist at compile-time!
If you don't need a class, here's a much shorter, much less-to-type solution that takes a type or instance and a simple array of strings as keys:
const pickSafely = <ObjectType>(keys: readonly `${string & keyof ObjectType}`[]) => {
return (object: any) => {
const resultObject: ObjectType = {} as unknown as ObjectType;
for (let index = 0; index < keys.length; index += 1) {
const key = keys[index] as unknown as keyof ObjectType;
resultObject[key] = object[key];
}
return resultObject as ObjectType;
}
}
This approach will save you keystrokes when it's time to use it:
// Imagine this came from your database.
const user = {
firstName: 'Bill',
favouriteColor: 'green',
creditCard: 'what is this doing here?',
};
// Imagine this is your model.
type User = {
firstName?: string;
favouriteColor?: string;
}
const userKeys = ['firstName', 'favouriteColor'] as const;
const pickUser = pickSafely<User>(userKeys); // No type error.
// And here's your application usage.
const safeUser = pickUser(user);
But more importantly, it protects you from picking a key that is NOT allowed by the type. This is useful if you want to use pickSafely to sanitize data coming from a user or strip out fields from a database responses before sending them over the wire.
// Imagine this came from your database.
const user = {
firstName: 'Bill',
favouriteColor: 'green',
creditCard: 'what is this doing here?',
};
// Imagine this is your model.
type User = {
firstName?: string;
favouriteColor?: string;
}
const userKeysWhoopsie = ['firstName', 'favouriteColor', 'creditCard'] as const;
const pickUserUhOh = pickSafely<User>(userKeysWhoopsie); // Shows a type error - hmm, picking a property you shouldn't?
// In your application
const pwndUser = pickUser(user); // This won't execute, it won't compile.
The magic bit of this solution is using Template Literal Types to dynamically generate a union of literal types from a normal Type.
This does NOT protect you from adding a property to ObjectType and forgetting to add it to keys - think of it as a whitelist that is itself whitelisted by the type ;)
Here's the type error this code produces in VSCode:

someObjectcontains more fields and you want extract only the fields inISpecific?