为什么这个索引签名不能是可选的?

时间:2019-08-03 11:16:05

标签: javascript typescript

在TypeScript中,有一个名为Partial<T>的预定义类型。定义如下:

type Partial<T> = {
  [P in keyof T]?: T[P];
}

显然,索引签名被标记为可选,并且可以工作。如果我尝试做同样的事情:

interface IDictionary<T> {
  [ key: string ]?: T
}

TypeScript抱怨?。这是因为接口可能不包含可选字段,还是这是什么原因?

1 个答案:

答案 0 :(得分:4)

否,打字稿界面允许使用可选字段。原因是逻辑上

Partial<T>限制了键的外观=> P in keyof T。 如果您在此处删除?,则意味着Partial<T>T相同。

interface Car {
  brand: string;
  color: string;
}

// this is exactly the same as the interface declaration below
type PartialCar = Partial<Car>;

// this is exactly the same as the type above
interface PartialCar = { 
  brand?: string;
  color?: string;
}

const carWithoutColor: PartialCar = { brand: "BMW" }
const thisIsStillAPartialCar: PartialCar = {}

与您的IDictionary<T>不同。您没有在键上添加约束(只是说它是任何 string)。因此,说它是可选的是没有意义的,因为它仍然是可选的(就其而言,它可以是任何 string)。
在您的IDictionary<T>中,您只是在值部分添加一个约束,该约束需要为T类型。

const numberDictionary: IDictionary<number> = { someStupidKey: 1, oneMoreKey: 2 }
const stringDictionary: IDictionary<string> = { someStupidKeyAWFSAFWAFW: "foo", oneMoreKey: "bar" }

// typescript will assume that "someVariable" is a number
const someVariable = numberDictionary.thisIsUndefined;

// which is why this will not end up in a compile error but a runtime error
const someResult =  1 + someVariable;

您可以看到,声明为IDictionary<T>

的每个键都是可选