我是Typescript的新手,并且一直在玩耍。我有此错误代码(为简单起见,已删除)。最终是用于redux动作/减速器,这就是为什么它有点复杂的原因。
interface StoreType {
bool: boolean,
num: number,
}
interface PayloadType {
key: keyof StoreType,
value: ???
}
let test: PayloadType = {
key: "bool",
value: 3 // should ideally fail if value is not a boolean
}
var obj: StoreType = { bool: true, num: 3 }
obj[test.key] = test.value // ts(2322) Type 'number' is not assignable to type 'never'
两部分问题:
是否有可能在value
中优化PayloadType
,以使test.value
的类型为boolean
,如果test.key == "bool"
的类型为{ {1}}是否为number
?我尝试了test.key === "num"
,但并没有足够的约束:(
是否可以使分配value: StoreType[keyof StoreType]
类型安全且无错误?我已经看到https://github.com/microsoft/TypeScript/issues/31663中的错误,但是我不确定该如何进行,也不知道这是否与问题1有关。
如果我错过了一些基本知识,我不会感到惊讶。
谢谢!
答案 0 :(得分:3)
在key
中将PayloadType
类型定义为具有K
约束的通用类型参数keyof StoreType
将达到目的:
interface PayloadType<K extends keyof StoreType> {
key: K,
value: StoreType[K]
}
let test: PayloadType<"bool"> = {
key: "bool",
value: true // ✅
}
let testError: PayloadType<"bool"> = {
key: "bool",
value: 3 // ?
}
var obj: StoreType = { bool: true, num: 3 }
obj[test.key] = test.value
StoreType[keyof StoreType]
在此示例中不起作用,因为keyof StoreType
解析为联合类型"bool" | "num"
。在"bool" | "num"
中对StoreType
的查找将解析为这些键的所有可能的返回类型number | boolean
。
通过将key
类型与K
一起声明为泛型类型参数PayloadType<"bool">
,表示您希望使用特定的密钥StoreType
(不是联合)。
答案 1 :(得分:1)
@ ford04可以很好地回答您所提出的问题,而不是您真正想要实现的目标。
没有任何理由(或者我没有看到)在您的有效负载中具有明确的类型信息。我要说的是,您在应披露域数据的地方披露了一些技术细节。所以对我来说这是错误的方法。
在这种意义上,应该以域信息的形式进行区分:
type ActionType = 'add_user' | 'get_user' | 'add_comment' | 'get_comment' // example action types
// type constructor to save us typing
type Action<T extends ActionType, P> = {
type: T,
payload: P
}
// specific actions
type UserId = number; // just for convenience and readability
type GetUserAction = Action<'get_user', UserId>
type User = {name: string} // example payload type
type AddUserAction = Action<'add_user', User>
// action creator
const getUser = (id: UserId):GetUserAction => ({type: 'get_user', payload: id});
有效负载也可以是主要类型,如上例中通过get_user
操作所看到的。这种方法是类型安全的,您不能使用错误的有效负载类型发送get_user
操作。希望对您有所帮助。