函数中的泛型不检查Typescript中的参数类型

时间:2019-09-12 03:11:21

标签: typescript

我期望打字稿会引发错误,因为我在EntryPoints中传递了错误数量的元素,但不会发生。

function createContext<T>(defaultValue: T): T[] {
  return [defaultValue]
}

interface EntryPoints {
  parentSelector: string;
}
interface SomeType {
  entryPoints: EntryPoints[];
}
const defaultData = {
  entryPoints: [{
    parentSelector: '',
    foo: 1 // <-- expecting error here
  }]
}
createContext<SomeType>(defaultData)

相同的代码没有预期的通用工作

function createContext<T>(defaultValue: T): T[] {
  return [defaultValue]
}

interface EntryPoints {
  parentSelector: string;
}
interface SomeType {
  entryPoints: EntryPoints[];
}
const defaultData: SomeType = {
  entryPoints: [{
    parentSelector: '',
    foo: 1 // <-- throwing error here
  }]
}
createContext(defaultData)

Playground

2 个答案:

答案 0 :(得分:2)

您遇到了object freshness issue,因此允许使用附加键。

如果您明确传递了该对象,则会对其进行正确键入检查:

function createContext<T>(defaultValue: T): T[] {
  return [defaultValue];
}

interface EntryPoints {
  parentSelector: string;
}

interface SomeType {
  entryPoints: EntryPoints[];
}

createContext<SomeType>({
  entryPoints: [
    {
      parentSelector: "",
      foo: 1 // <-- errors as expected here
    }
  ]
});

TypeScript Playground

答案 1 :(得分:1)

您所经历的是

之间的区别
    在为类型分配文字和时进行
  1. 类型检查 在为类型分配变量时进行
  2. 类型检查。

请考虑我们有两种类型。其中一个比另一个具有更多的属性。

type Foo = {
  foo: string;
};

type FooBar = {
  foo: string;
  bar: string;
};

为类型分配对象文字时,不允许其他属性

// Object literal may only specify known properties,
// and 'bar' does not exist in type 'Foo'.
const foo: Foo = {
  foo: "foo",
  bar: "bar" // <---- bar is not allowed on Foo.
};

为类型分配变量时,允许其他属性

const fooBar: FooBar = {
  foo: "foo",
  bar: "bar" // <---- bar is going to be allowed on Foo
};

const foo: Foo = fooBar; // <---- see, no error

可以将fooBar分配给foo,因为fooBar是一个变量,而不是对象常量,因此可以包含未知属性。