我正在尝试使用Typescript改善我的项目,但我不知道如何使以下内容正常工作。
说我有一个像这样简单的函数表达式
const foo = (objectLiteral: any): void => {
console.log(objectLiteral)
}
现在,我将像这样使用它。
foo({
name: 'guybrush',
nestedProperties: {
gunPowderAmount: 1
},
speak () {
// First issue, "this" is any type. I don't get any intellisense for the properties
// within the object.
// this.
}
})
根据我在语音函数中的注释,“ this”具有任何类型,并且我无法访问该对象的任何属性。我认为这与此https://github.com/microsoft/TypeScript/issues/11072有关。
我知道这与打字稿无关-但是-我要到达那里。
然后我假设,因为我使用的是打字稿,所以我可以利用类型,太酷了! 因此,我的代码更改为以下内容:
type MappedCharacter = {
name: string;
speak: () => void;
nestedProperties: { [key: string]: number | string };
}
const foo2 = (objectLiteral: MappedCharacter) => {
console.log(objectLiteral)
}
我将像这样使用它:
foo2({
name: 'guybrush',
nestedProperties: {
gunPowderAmount: 1
},
speak () {
// Second issue. Now "this" has access to the properties, but NOT
// the one which are NESTED into "nestedProperties"
}
})
很酷,我现在可以访问“ this”,并且可以将属性“ name”和“ nestedProperties”作为目标。
但是,嘿,“ nestedProperties”还有其他属性!他们在哪里?
最终测试,我将摆脱函数表达式,而仅对对象进行测试。
const objectLiteral: MappedCharacter = {
name: 'guybrush',
nestedProperties: {
gunPowderAmount: 1
},
speak () {
// Third issue. Even if not used in a function, "this.nestedProperties" can't dig any
// deeper.
// this.nestedProperties.
}
}
从语音功能中的注释来看,再次使该嵌套属性起作用没有运气。
我也没有运气尝试过,将我的类型更改为:
type MappedCharacter = {
name: string;
speak: () => void;
nestedProperties: keyof MappedCharacter['nestedProperties'];
}
'nestedProperties'的结果直接或间接在其自己的类型注释中引用
编辑: 我不想为“ nestedProperties”对象定义类型。 我只是希望它尽可能通用,因为我无法预见它可以拥有什么样的属性。
EDIT2: 如果我有一个普通的对象文字,没有任何类型,vscode可以确定这些属性,使其尽可能嵌套。我想用类型实现相同的行为。 我通常在具有Vetur扩展功能的项目中使用Vuejs,并且当为数据函数定义不同的属性时,智能感知就可以了。
任何人都可以阐明这个问题吗? 难题的缺失部分是什么?
答案 0 :(得分:-1)
定义MappedCharacter
类型时,基本上是说nestedProperties
具有 some 属性。您没有定义哪个,因此编译器没有此信息。
然后,您创建objectLiteral
对象,其中nestedProperties
具有gunPowderAmount
属性-但这仅适用于该特定对象,并且在该特定时刻。仍然会根据speak()
类型对MappedCharacter
函数进行类型检查,该类型在任何地方都没有定义gunPowderAmount
属性。
我建议,如果您知道MappedCharacter
会有哪些不同的特性,请这样定义:
type MappedCharacter<TProps> = {
name: string;
speak: () => void;
nestedProperties: TProps
}
type GuybrushProps = {
gunPowderAmount: number
}
const objectLiteral: MappedCharacter<GuybrushProps> = {
name: 'guybrush',
nestedProperties: {
gunPowderAmount: 1
},
speak () {
// Then, intellisense here should work as you expect it to
}
}