LaV*_*che 6 types interface type-hinting type-safety typescript
在Typescript中,您可以声明数组中的所有元素都是这样的类型:
const theArray: MyInterface[]
Run Code Online (Sandbox Code Playgroud)
是否有类似的东西可以声明所有对象的属性值必须是同一类型?(没有指定每个属性名称)
例如,我目前正在这样做:
interface MyInterface {
name:string;
}
const allTheThingsCurrently = {
first: <MyInterface>{name: 'first thing name' },
second: <MyInterface>{name: 'second thing name' },
third: <MyInterface>{name: 'third thing name' },
//...
};
Run Code Online (Sandbox Code Playgroud)
...注意我必须<MyInterface>
为每个属性指定.这有什么捷径吗?即我想象这样的事情......
const allTheThingsWanted:MyInterface{} = {
first: {name: 'first thing name' },
second: {name: 'second thing name' },
third: {name: 'third thing name' },
//...
};
Run Code Online (Sandbox Code Playgroud)
MyInterface{}
是无效代码的部分,我正在寻找一种更少冗余的方法,以及可选的额外严格性,以防止任何其他属性添加到不同类型的对象.
kin*_*aro 14
interface Thing {
name: string
}
interface ThingMap {
[thingName: string]: Thing
}
const allTheThings: ThingMap = {
first: { name: "first thing name" },
second: { name: "second thing name" },
third: { name: "third thing name" },
}
Run Code Online (Sandbox Code Playgroud)
这里的缺点是你可以访问任何属性而allTheThings
没有任何错误:
allTheThings.nonexistent // type is Thing
Run Code Online (Sandbox Code Playgroud)
通过定义ThingMap
as 可以使这更安全[thingName: string]: Thing | void
,但即使您正在访问您知道存在的属性,也需要在整个地方进行空检查.
const createThings = <M extends ThingMap>(things: M) => things
const allTheThings = createThings({
first: { name: "first thing name" },
second: { name: "second thing name" },
third: { name: "third thing name" },
fourth: { oops: 'lol!' }, // error here
})
allTheThings.first
allTheThings.nonexistent // comment out "fourth" above, error here
Run Code Online (Sandbox Code Playgroud)
该createThings
函数具有泛型M
,并且M
可以是任何东西,只要所有值都是Thing
,然后它返回M
.传入一个对象时,它会根据该类型对该类型进行验证extends
,同时返回与传入的内容相同的形状.
这是"最聪明"的解决方案,但使用一个看起来有点聪明的黑客来实际让它工作.无论如何,在TS添加更好的模式来支持这样的情况之前,这将是我的首选路线.
单层(平面)对象的一些替代方案:
const exampleObj: { [k: string]: string } = {
first: 'premier',
second: 'deuxieme',
third: 'troisieme',
}
Run Code Online (Sandbox Code Playgroud)
const exampleObj: Record<string, string> = {
first: 'premier',
second: 'deuxieme',
third: 'troisieme',
}
Run Code Online (Sandbox Code Playgroud)
const exampleObj: Record<'first' | 'second' | 'third', string> = {
first: 'premier',
second: 'deuxieme',
third: 'troisieme',
}
Run Code Online (Sandbox Code Playgroud)
使用泛型并指定您想要的属性类型。
type SamePropTypeOnly<T> = {
[P: string]: T;
}
interface MyInterface {
name: string;
}
const newObj: SamePropTypeOnly<MyInterface> = {
first: { name: 'first thing name' },
second: { name: 'second thing name' },
third: { name: 'third thing name' },
// forth: 'Blah' // Type 'string' is not assignable to type `MyInterface`
}
newObj.not_there; // undefined - no error
Run Code Online (Sandbox Code Playgroud)
注意:如果必须限制属性名称列表,则必须明确指定键:
interface MyInterface {
name: string;
}
type OptionKeys = 'first' | 'second' | 'third';
const newObj: Record<OptionKeys, MyInterface> = {
first: { name: 'first thing name' },
second: { name: 'second thing name' },
third: { name: 'third thing name' },
// forth: 'Blah' // error
}
newObj.not_there // Property 'not_there' does not exist on type...
Run Code Online (Sandbox Code Playgroud)