Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么不是';需要我的函数返回特定类型的t类型脚本?_Javascript_Typescript - Fatal编程技术网

Javascript 为什么不是';需要我的函数返回特定类型的t类型脚本?

Javascript 为什么不是';需要我的函数返回特定类型的t类型脚本?,javascript,typescript,Javascript,Typescript,我有一个通用的Factory函数,它应该返回一个特定类型: type Factory<T> = () => T; interface Widget { creationTime: number; } const build: Factory<Widget> = () => { return { creationTime: Date.now(), foo: 'bar', }; }; 有没有办法让Typescript将相同的“严格

我有一个通用的
Factory
函数,它应该返回一个特定类型:

type Factory<T> = () => T;

interface Widget {
  creationTime: number;
}

const build: Factory<Widget> = () => {
  return {
    creationTime: Date.now(),
    foo: 'bar',
  };
};

有没有办法让Typescript将相同的“严格性”分配给我的通用
工厂
类型?

Typescript中的对象类型通常不禁止额外的属性。它们是“开放的”或“可扩展的”,而不是“封闭的”或“精确的”(参见)。否则就不可能使用子类或接口扩展:

interface FooWidget extends Widget {
   foo: string;
}
const f: FooWidget = { creationTime: 123, foo: "baz" };
const w: Widget = f; // okay
有时人们想要这种“精确”的类型,但它们并不是语言的一部分。相反,TypeScript所拥有的是,这只发生在非常特殊的情况下:当一个“新鲜”的对象文本被赋予一个不知道该对象文本中某些属性的类型时:

const x: Widget = { creationTime: 123, foo: "baz" }; // error, what's foo
如果尚未将对象文字指定给任何类型,则该对象文字为“新鲜”。
x
w
之间的唯一区别在于
x
中的文字是“新鲜”的,并且禁止使用过多的属性,而
w
中的文字是。。。UH“stale”,因为它已经被赋予类型
FooWidget


由此看来,您的
widgetFactory
应该会给出一个错误,因为您返回的对象文本没有在任何地方赋值。不幸的是,在这种情况下,新鲜度丧失了。有一个长期存在的问题,注意到这一点,并取决于一个非常古老的问题。当检查返回的类型是否与预期的返回类型兼容时,TypeScript会自动加宽返回的类型。。。新鲜感也会消失。看起来没人喜欢这个,但是。所以现在,它是什么


您已经有了一个解决方法:显式注释函数的返回类型。这不是特别令人满意,但它完成了工作

export const WidgetFactory1: Factory<Widget> = {
   build: (): Widget => {
      return {
         creationTime: Date.now(),
         foo: 'bar', // error!
      };
   },
};
导出常量WidgetFactory1:工厂={
构建:():小部件=>{
返回{
creationTime:Date.now(),
foo:'bar',//错误!
};
},
};
其他解决方法包括强制编译器计算精确的类型,这是可能的,但比您现在所做的要难看得多:

const exactWidgetFactory =
   <W extends Widget & Record<Exclude<keyof W, keyof Widget>, never>>(
      w: Factory<W>) => w;

export const WidgetFactory2 = exactWidgetFactory({
   build: () => { // error!
// ~~~~~ <-- types of property foo are incompatible
      return {
         creationTime: Date.now(),
         foo: 'bar',
      };
   },
});
const exactWidgetFactory=
(
w:工厂)=>w;
导出常量WidgetFactory2=exactWidgetFactory({
生成:()=>{//错误!
// ~~~~~
const exactWidgetFactory =
   <W extends Widget & Record<Exclude<keyof W, keyof Widget>, never>>(
      w: Factory<W>) => w;

export const WidgetFactory2 = exactWidgetFactory({
   build: () => { // error!
// ~~~~~ <-- types of property foo are incompatible
      return {
         creationTime: Date.now(),
         foo: 'bar',
      };
   },
});