简体   繁体   中英

Declare type of inline object with TypeScript

As you can see I create an object inline, and I don't know how to declare the type of this object.

     zuite.getAfters().push({    // inline object here
        timeout: obj.opts.timeout || 11000,
        desc: obj.desc || (obj.fn ? obj.fn.name : '(unknown)'),
        fn: obj.fn,
        type: 'after/teardown',
        warningErr: new Error('SUMAN_TEMP_WARNING_ERROR')
      });

zuite and getAfters() have the following signatures:

type TestSuiteGetterFn <T> = () => Array<T>;


interface Zuite {

    injectedValues: Object,
    getInjections: Function,
    getAfters: TestSuiteGetterFn<any>,

}

do I need to declare the type inline? Or do I just rely on the type declared in the Zuite interface and TestSuiteGetterFn type? (In this case it's just any but I would updated that.

You don't need to declare the type of the object. Types are only a compile-time artifact. So that means the you should use them to discover compile time errors. Trying to add a type to inline object makes no difference really, as TypeScript is structurally typed

What you should do though, is type the TestSuiteGetterFn . This will in turn, give strong typing to the array. What this does is make sure that the inline object matches the structure of the type you give to the array it returns. This will allow you to catch structural errors in the object literal

eg

type TestSuiteGetterFn <T> = () => Array<T>;

interface Message {
  message: string;
}

interface Zuite {
  getAfters: TestSuiteGetterFn<Message>,
}

Fail

zuite.getAfters().push({
  badProperty: true
})

The above will cause a compile error because the structure of the object literal doesn't match the Message type (here is structural typing in play).

OK

zuite.getAfters().push({
  message: 'hey there'
})

Here the object literal matches the Message type structure, so no compile error.

You can create a new type for your object literal and change the declaration for Zuite.getAfters :

interface SomeType {
    ctx: Zuite,
    timeout: number
    // ...and so on
}

type TestSuiteGetterFn <T> = () => Array<T>;

interface Zuite {    
    injectedValues: Object,
    getInjections: Function,
    getAfters: TestSuiteGetterFn<SomeType>, // Notice `SomeType` instead of `any`
}

// Your object literal is typed as `SomeType` now
zuite.getAfters().push({
    ctx: zuite,
    timeout: obj.opts.timeout || 11000,
    // ...and so on
});

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