This is not possible on typescript 4.0.
But on the unreleased 4.1 beta via Template Literal Types you have some options!
If you're new to typescript this will look a bit strange:
type UrlKeys<T> = {
[K in keyof T]: K extends `${infer Prefix}_url` ? K : never
}[keyof T]
type RemoveUrls<T> = Omit<T, UrlKeys<T>>
The UrlKeys type iterates over an objects properties. For each key, if the key K has some Prefix followed by a _url at the end, then return that key name, else return never. The [keyof T] at the end gets a union of all the keys that were not assigned to never.
Then RemoveUrls simply takes a type and Omits any keys that would be considered _urls.
You would use those types like this:
function removeUrls<T>(target: T): RemoveUrls<T> {
const result: Partial<T> = {}
for (const key in target) {
if (!key.includes('_url')) {
result[key] = target[key]
}
}
return result as T;
}
const result = removeUrls({ a: 123, b_url: 'http://example.com' }) // type: { a: number }
Note that this function is now has the T generic parameter to accept any type. And the return value is the the same type, minus the url properties.
Also, when building an object one property at a time like this, you would need to type the in progress object as a Partial to make it okay that not all properties are present while being constructed. Then in the return statement, you can cast it back to a full T since you know you have processed all the properties.
Playground