John Hou
John Hou

Reputation: 239

The example of intersection type in typescript official documentation doesn't works

The example code of intersection type in typescript official documentation doesn't works.

I am learning typescript, and typing the example code of intersection type in to Playground editor , and i got some error tips. as a picture shows below:

enter image description here

how to fix them?

----- Update Again ------

The recommended one is as below, more details can find in the comments!

function extend<First extends object, Second extends object>(first: First, second: Second): First & Second {
    const result: Partial<First & Second> = {};
    for (const prop in first) {
        if (first.hasOwnProperty(prop)) {
            (result as unknown as First)[prop] = first[prop];
        }
    }
    for (const prop in second) {
        if (second.hasOwnProperty(prop)) {
            (result as unknown as Second)[prop] = second[prop];
        }
    }
    return result as unknown as First & Second;
}

class Person {
    constructor(public name: string) { }
}

interface Loggable {
    log(name: string): void;
}

class ConsoleLogger implements Loggable {
    log(name: string) {
        console.log(`Hello, I'm ${name}.`);
    }
}

const jim = extend(new Person('Jim'), ConsoleLogger.prototype);
jim.log(jim.name);

Upvotes: 1

Views: 203

Answers (1)

pascalpuetz
pascalpuetz

Reputation: 5418

Like this:

// hasOwnProperty is part of "object", so we specify the Generic needs to be a subtype of Object - or rather a "non-primitive" type.
function extend<First extends object, Second extends object>(first: First, second: Second): First & Second {
    const result: Partial<First & Second> = {};
    for (const prop in first) {
        if (first.hasOwnProperty(prop)) {
            // TypeScript suspects an error here, that's why we need to convert to unknown first
            (result as unknown as First)[prop] = first[prop];
        }
    }
    for (const prop in second) {
        if (second.hasOwnProperty(prop)) {
            (result as unknown as Second)[prop] = second[prop];
        }
    }
    return result as unknown as First & Second;
}

class Person {
    constructor(public name: string) { }
}

interface Loggable {
    log(name: string): void;
}

class ConsoleLogger implements Loggable {
    log(name: string) { // Implicit any, we know it needs to be of type "string" though, so we can just type it
        console.log(`Hello, I'm ${name}.`);
    }
}

const jim = extend(new Person('Jim'), ConsoleLogger.prototype);
jim.log(jim.name);

Upvotes: 1

Related Questions