5

there are function in 3rd party libraries that extends objects to add to them more functions. e.g. seamless-immutable

I want to create definition file for such a library. I thought something in the line of

interface ImmutableMethods<T> extends T{
    set?<U>(key: string | number, value: any): T | U;
    setIn?<U>(keys: Array<string>, value: any): T | U;
    ...
}
function Immutable<T>(obj: T, options?): ImmutableMethods<T>

Then I will be able to declare my own types as:

interface Type1 {prop1, prop2}
interface Type2 {propOfType1: ImmutableMethods<Type1>}
var immutableType2:Type2 = Immutable(...)

And then I'll have the Immutable's function on all my objects.

But the problem is that the line interface ImmutableMethods<T> extends T gives me an error "An interface may only extend a class or another interface"

Is there a way to declare that T is an interface, or a whole other way to get this extending behavior?

3
  • I don't see why you want to use extends T on your interface. Can't you just extend from Immutable<T> Commented Feb 23, 2016 at 15:22
  • 1
    I don't want to couple my business logic interface with implementation details of the library I'm working with. Another thing is that there is a need to pass arrays and mapping so instead of just writing x: ImmutableMethods<Array<MyInterface>>, I need to somehow create a new kind of Array object. Commented Feb 25, 2016 at 6:47
  • FYI, I posted an issue on the seamless-immutable repo regarding typings: github.com/rtfeldman/seamless-immutable/issues/108 Commented Mar 7, 2016 at 12:07

1 Answer 1

2

You can use intersection types to attain this behavior. Define an interface for the extra functions and define a type that is T & Interface. My modifications to your code:

interface ImmutableMethods<T> {
    set?<U>(key: string | number, value: any): T | U;
    setIn?<U>(keys: Array<string>, value: any): T | U;
}
type ImmutableExtended<T> = ImmutableMethods<T> & T;

interface Type1 { prop1: string, prop2: string }
interface Type2 { propOfType1: ImmutableExtended<Type1> }
var immutableType2: Type2 = ...;

The ImmutableMethods<T> interface defines the functions involved. The ImmutableExtended<T> type is the interface we actually want to use for the extended objects, though of course you can name these interfaces whatever you like.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.