Typescript 初始化前无法访问[variable]

Typescript 初始化前无法访问[variable],typescript,typescript-typings,Typescript,Typescript Typings,我试图创建一个“可移动实体”,它在“移动”时返回一个新状态。我遇到了两个错误,我不知道如何解决。第一个是当我从一个实体创建一个可移动对象时,我需要用一个“move”对象填充该实体。此对象依赖于这样一个事实:父对象现在将有一个“移动”对象作为子对象。您可以在1)中看到具体的错误(这仍然运行,我只希望正确键入它) 对于2),我无法调用entity.move.nextState(),我不确定为什么。这是主要的拦截器。有什么想法吗 下面是一个示例中的代码 (跳到testMove,了解函数的作用) typ

我试图创建一个“可移动实体”,它在“移动”时返回一个新状态。我遇到了两个错误,我不知道如何解决。第一个是当我从一个实体创建一个可移动对象时,我需要用一个“move”对象填充该实体。此对象依赖于这样一个事实:父对象现在将有一个“移动”对象作为子对象。您可以在
1)
中看到具体的错误(这仍然运行,我只希望正确键入它)

对于
2)
,我无法调用
entity.move.nextState()
,我不确定为什么。这是主要的拦截器。有什么想法吗

下面是一个示例中的代码

(跳到
testMove
,了解函数的作用)

type Nullable=T | null
界面离子晶体{
id:字符串
}
界面位置{
x:编号,y:编号,z:编号
}
接口IComponent扩展了IEntityState{}
可操作的接口{
nextState:(…参数:任意)=>IEntityState
}
接口可撤消{
初始状态:可为空
撤消:()=>IEntityState |错误//TODO做一个
提交:()=>IEntityState
}
/**可移动*/
接口IMoveAction扩展了可操作、可撤消{
初始状态:可为空
下一状态:(位置:i位置)=>i移动
撤消:()=>iMoved|错误
提交:()=>iMoved
} 
接口IMovable扩展了IComponent{
位置:IPosition
移动:移动
}
const MoveAction=(对象:O):imovAction=>
({
initialState:null,
//如果初始移动状态不存在,则返回初始移动状态
下一状态:(位置:i位置):i移动=>
初始状态
?{…对象,位置}
:{…对象,位置,移动:{…对象。移动,初始状态:位置}
,
撤消:()=>
初始状态
?{…对象,位置:initialState,移动:{…对象.move,initialState:null}
:新错误('无法撤消没有初始状态的移动')
,
提交:()=>
({…对象,位置:initialState,移动:{…对象.move,initialState:null})
,
})
键入MovableInput=IEntityState&{position:IPosition}
常量可移动=(对象:O):O&i可移动=>
({
对象
move:MoveAction(对象),//1)类型为“O”的参数不可分配给类型为“IMovable”的参数。类型为“MovableInput”中缺少属性“move”,但类型为“IMovable”中需要属性“move”
})
函数testMove(){
console.log('正在运行移动组件测试')
常量id='test'
常量initialPosition:IPosition={x:3,y:2,z:3}
常量newPosition:IPosition={x:3,y:2,z:0}
常量实体:MovableInput={id,位置:initialPosition}
常量initialState=可移动(实体)
//2)引发错误“无法在初始化之前访问“initialState”
const nextState=initialState.move.nextState(newPosition)
const undoneState=nextState.move.undo()作为IMovable
//初始状态保持不变
断言(initialPosition==nextState.move.initialState)
//状态转换是否正确
console.assert(initialState.position!==nextState.position)
//我们可以撤销行动
console.assert(nextState.position!==undoneState.position)
console.assert(initialState.position==undownestate.position)
//我们无法撤消已提交的更改
const committedState=nextState.move.commit()
const error=committedState.move.undo()作为错误
console.assert(error.message==“无法撤消没有初始状态的移动”)
}testMove()

在创建
MoveAction
对象之前,尝试使用对象属性
initialState
。一个解决方案是使用getter,这是重写代码并使用类而不是普通对象的更好的解决方案

getter方法如下所示:

const MoveAction = <O extends IMovable>(object: O): IMoveAction => 
({
    initialState: null,
    // Return with an initial move state if it does not exist already
    get nextState() { return function(position: IPosition): IMovable {
        return this.initialState
            ? { ...object, position }
            : { ...object, position, move: { ...object.move, initialState: position } }
            }
        },
    get undo() { return function() { 
        return this.initialState
            ? { ...object, position: this.initialState, move: { ...object.move, initialState: null } }
            : new Error('Cannot undo a move with no initialState')
        }
    },
    get commit() {return function() { 
        return ({ ...object, position: this.initialState, move: { ...object.move, initialState: null } })
    }},
})

常量移动
中,我返回一个新对象,该对象包含
初始状态
下一状态
撤消
提交
。为什么这个对象没有初始化?另外,我试图避免使用类,而只使用简单的对象。那么为什么要使用关于使用类的typescript呢?避免这种情况的原因是什么,您的代码真的很难理解。上课会容易得多。老实说,我可能走错了路,但我正试图让一切都正常运作,因此尽量避免上课。Typescript很有用,因为它提供了类型提示对不起,我错了,被引用的答案误导了。您的方法有效,只需小心使用“this”和箭头函数。我在答案中添加了一个固定的
MoveAction
。因此,当调用
nextState
时,为什么对象会丢失其undo属性?
const MoveAction = <O extends IMovable>(object: O): IMoveAction => 
({
    initialState: null,
    // Return with an initial move state if it does not exist already
    get nextState() { return function(position: IPosition): IMovable {
        return this.initialState
            ? { ...object, position }
            : { ...object, position, move: { ...object.move, initialState: position } }
            }
        },
    get undo() { return function() { 
        return this.initialState
            ? { ...object, position: this.initialState, move: { ...object.move, initialState: null } }
            : new Error('Cannot undo a move with no initialState')
        }
    },
    get commit() {return function() { 
        return ({ ...object, position: this.initialState, move: { ...object.move, initialState: null } })
    }},
})
const MoveAction = <O extends IMovable>(object: O): IMoveAction => 
({
    initialState: null,
    // Return with an initial move state if it does not exist already
    nextState(position: IPosition): IMovable {
        return this.initialState
            ? { ...object, position }
            : { ...object, position, move: { ...object.move, initialState: position } }
    },
    undo(): IMovable | Error { 
        return this.initialState
            ? { ...object, position: this.initialState, move: { ...object.move, initialState: null } }
            : new Error('Cannot undo a move with no initialState')
    },
    commit(): IMovable{ 
        return { ...object, position: this.initialState, move: { ...object.move, initialState: null } }
    },
})