Luka Horvat
Luka Horvat

Reputation: 4412

Function that takes any type and it's subtype

I want to write the following function

function override<T, U>(first: T, second: U): T {
    let result = <T>{};
    for (let id in first) {
        result[id] = first[id];
    }
    for (let id in second) {
        result[id] = second[id];
    }
    return result;
}

but make it typesafe. In my use case, both T and U are simple records types. I want T to be required to have all the properties of U. Is there a way to express this relation?

Upvotes: 3

Views: 926

Answers (2)

Yousef Salimpour
Yousef Salimpour

Reputation: 714

I know its an old question but currently TS supports the following syntax:

type Partial<T> = { [P in keyof T]?: T[P]; }

(Which is in lib.d.ts so you may not need to include it in your code)

So:

function override<T>(first: T, second: Partial<T>): T { ...

Upvotes: 0

basarat
basarat

Reputation: 276115

You cannot do that in a single function declaration. The reason is that extends generic constrain cannot reference other generics in the same group. However you can split the function into two parts (currying). And then use the type of the first argument (now in a separate function) to constrain the type of the second argument as shown below:

var override = <T>(first:T) => <U extends T>(second:U) : T => {
    let result = <T>{};
    for (let id in first) {
        result[id] = first[id];
    }
    for (let id in second) {
        result[id] = second[id];
    }
    return result;
}

override({a:123})({a:123, b:456}); // okay 
override({a:123})({b:456}); // error

Upvotes: 4

Related Questions