2016-12-03 67 views
0

我对TypeScript非常陌生。我有一个场景,我想将一个类型赋值给一个变量,该变量的值是从第三方库函数返回的,并且具有它自己的类型定义。期待来自第三方库函数的'Type'

例如:

import {omit} from 'lodash' 

interface ITest { 
    a: String; 
} 

const foo: Object = { 
    a: "dfdf", 
    b: "sdfsdf", 
} 

const expected: ITest = omit(foo, 'b') 

这显示该错误

[TS]类型 '{}' 不是分配给输入 'ITEST'。

类型'{}'中缺少属性'a'。

我是做错了还是不可能?

回答

1

发生这种情况是因为omit对返回类型的限制很少,默认返回{}。看看the definitions for omit,如果你想挖成这样:

interface LoDashStatic { 
    omit<TResult extends {}, T extends {}>(
     object: T, 
     ...predicate: (StringRepresentable|StringRepresentable[])[] 
    ): TResult; 
} 

这是说省略有两个泛型参数(TResultT,这都至少为{})。它还有一个必需的参数(object)和0或更多predicate(字符串,或多或少)。泛型参数T是其输入的类型,而TResult是该函数的总体返回类型。

当您不指定泛型参数时,TypeScript会推断它们。这些参数虽然相互之间没有关系,或者其他很多,所以很难做到这一点。它可以推断出T:它是它给出的参数的类型。对于TResult虽然,它什么都没有。如果您调用该函数并立即使用该值,则在某些情况下,这足以进行推理以计算该函数预期会返回的内容(所以TResult是),但在您的情况中不是,因此推断为{}

一旦你居然叫在你的代码省略,你再尝试分配{}ITest,这是不绝对安全 - 这是可能得到不具有a属性的空对象,这不会是正确的。

你有两个选项排序了这一点:

  • 使用类型断言:const expected = <ITest> omit(foo, 'b')

    在这里,我们告诉你是知道这是一个ITest编译器。它会允许(并给expected一个ITest类型),只要它是可能你是正确的 - 你不必是肯定正确,因为你做了平原的任务。

  • 通过提供omit明确使用的通用参数来指定函数的返回类型:const expected = omit<ITest, {}>(foo, 'b')

    当前这些参数是自动推断出来的,但这些类型定义没有任何方法来派生'正确'类型(“foo的类型,但没有'a'”),所以你最终得到最普遍的返回类型可能是:{}。如果你明确地设置了这些泛型,你可以更密切地控制它。你只是真的想在这里指定一个泛型参数(返回类型),但是你不能那么伤心:你必须既指定也不指定。

就我个人而言,我会使用类型断言,但我认为从这一点来看它归结为个人品味的问题。

+0

说得好。省略(foo,'b')'中的'{}'是什么意思? –

+0

我已经在类型定义本身上添加了更多细节。有两个通用参数 - TResult和T - 并且省略(foo,'b')'将TResult设置为ITest,T设置为{}。 TResult是返回类型(这是你想要改变的),而T是参数(foo)的类型,你可能不关心,但是如果你想指定一个,你必须指定两者。 –