简体   繁体   中英

Typescript Extend Generic Interface

I want to create an interface whereby I can extend any typescript type to add a property to extend a generic type. For example, create a Confidence<any> type that looks like this:

export interface Confidence<T> extends T{
   confidenceLevel:number
}

It can then be accessed by going:

const date:Confidence<Date> = new Date();
date.confidenceLevel = .9;

This does not seem to be possible (and I get the feeling it is anti-pattern), however I can do

export type Confidence<T> = T & {
   confidenceLevel:number
}

Which appears to accomplish what I want to do though I feel like I'm cheating doing this.

I recognize this "reverse extension" could be problematic if I overwrite a property of the generic type, but is that the only concern? I'm having trouble wrapping my head around this, what is the best way to create a type that merely adds a property?

There is a longstanding feature request, microsoft/TypeScript#2225 , which asks for the ability to do interface Foo<T> extends T {...} the way you are asking for it. It's not implemented yet (and might never be). Right now you can only make an interface that extends an object type with statically known keys . The unspecified generic type parameter T does not work because the compiler cannot predict what keys it will have.

You should rest assured that an intersection is a reasonable way of achieving this (with the caveat that you will not be warned if your added property conflicts with a property of T , as you noticed). It is the suggested solution in the aforementioned feature request. Additionally, the TypeScript library typings for Object.assign() use an intersection to represent the type of the result of adding properties to an existing object. Therefore, with Confidence<T> defined like

type Confidence<T> = T & {
  confidenceLevel: number
}

you can easily write a function that produces one of these like this:

function makeConfidence<T>(x: T, confidenceLevel: number): Confidence<T> {
  return Object.assign(x, { confidenceLevel });
}

and use it:

const x = makeConfidence(new Date(), 0.9); // x is a Confidence<Date>;
console.log(x.getFullYear()); // 2020
console.log(x.confidenceLevel); 0.9

Looks good. Okay, hope that helps; good luck!

Playground link to code

您的最后一个代码片段是正确的做法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM