Μια ενημερωμένη απάντηση: μετά την προσθήκη των τύπων τομής μέσω &, είναι δυνατόν να «συγχώνευση» δύο συναχθεί τύπους on the fly.
Εδώ είναι μια γενική βοηθός που διαβάζει τις ιδιότητες κάποιου αντικειμένου fromκαι των αντιγράφων τους πάνω από ένα αντικείμενο onto. Επιστρέφει το ίδιο αντικείμενο onto, αλλά με ένα νέο τύπο που περιλαμβάνει δύο σύνολα των ακινήτων, τόσο σωστά περιγράφει τη συμπεριφορά χρόνου εκτέλεσης:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}
Αυτό το βοηθητικό χαμηλού επιπέδου έχει ακόμη εκτελέσει τύπου ισχυρισμό, αλλά είναι τύπου ασφαλές από το σχεδιασμό. Με αυτό το βοηθητικό στη θέση του, έχουμε ένα φορέα που μπορούμε να χρησιμοποιήσουμε για να λύσει το πρόβλημα του Ε.Π., με πλήρη ασφάλεια τύπο:
interface Foo {
(message: string): void;
bar(count: number): void;
}
const foo: Foo = merge(
(message: string) => console.log(`message is ${message}`), {
bar(count: number) {
console.log(`bar was passed ${count}`)
}
}
);
Κάντε κλικ εδώ για να το δοκιμάσετε στο γραφομηχανή χαρά . Σημειώστε ότι έχουμε περιορίζεται fooνα είναι του τύπου Foo, έτσι ώστε το αποτέλεσμα mergeπρέπει να είναι πλήρης Foo. Έτσι, αν μετονομάσετε barσε badσυνέχεια μπορείτε να πάρετε ένα σφάλμα τύπου.
Σημείωση: Υπάρχει ακόμα μια τρύπα τύπο εδώ, όμως. Γραφομηχανή δεν παρέχει έναν τρόπο για να περιορίσουν μια παράμετρο τύπου να είναι «δεν είναι μια λειτουργία». Έτσι, μπορείτε να μπερδευτείτε και να περάσει τη λειτουργία σας ως το δεύτερο επιχείρημα merge, και αυτό δεν θα μπορούσε να λειτουργήσει. Έτσι, μέχρι αυτό μπορεί να δηλωθεί, θα πρέπει να το πιάσει κατά το χρόνο εκτέλεσης:
function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
if (typeof from !== "object" || from instanceof Array) {
throw new Error("merge: 'from' must be an ordinary object");
}
Object.keys(from).forEach(key => onto[key] = from[key]);
return onto as T1 & T2;
}