在学习Typescript的过程中,我遇到了一个问题,当我使用常量变量和action的值时,我用它来减速(创建是为了防止打字-我在某处读到过,这是一个很好的实践)。
const INPUT_CHANGE: string = "INPUT_CHANGE";
const INPUT_BLUR: string = "INPUT_BLUR";
我还创建了类型来定义减速机的动作:
type InputReducerAction =
| { type: INPUT_CHANGE; value: string; isValid: boolean }
| { type: INPUT_BLUR };
这是我的减速器:
const inputReducer = (state: InputReducerState, action: InputReducerAction) => {
switch (action.type) {
case INPUT_CHANGE:
return {
...state,
value: action.value,
isValid: action.isValid,
};
case INPUT_BLUR:
return {
...state,
touched: true,
};
default:
return state;
}
};
当我有以上所有想法时,InputReducerAction
中的INPUT_CHANGE
和INPUT_BLUR
被标记为错误:
'INPUT_CHANGE'指向一个值,但在这里被用作类型。你是说'typeof INPUT_CHANGE'吗?ts(2749)
'INPUT_BLUR'指的是一个值,但在这里被用作类型。你是说'typeof INPUT_BLUR'吗?ts(2749)
当我对这些常量使用双引号时,问题就消失了,像这样
type InputReducerAction =
| { type: "INPUT_CHANGE"; value: string; isValid: boolean }
| { type: "INPUT_BLUR" };
但是我的const变量现在是无用的。我做错了什么或错过了什么?
在写这个问题的时候,我想到了使用enum:
enum INPUT_ACTION {
INPUT_CHANGE = "INPUT_CHANGE",
INPUT_BLUR = "INPUT_BLUR"
}
type InputReducerAction =
| { type: INPUT_ACTION.INPUT_CHANGE; value: string; isValid: boolean }
| { type: INPUT_ACTION.INPUT_BLUR };
const inputReducer = (state: InputReducerState, action: InputReducerAction) => {
switch (action.type) {
case INPUT_ACTION.INPUT_CHANGE:
return {
...state,
value: action.value,
isValid: action.isValid,
};
case INPUT_ACTION.INPUT_BLUR:
return {
...state,
touched: true,
};
default:
return state;
}
};
并在减速机和类型中使用。错误消失了,但是这是一个好主意吗?或者我可以用更好的方式做这件事吗?
您可以在v3.4之后使用const断言来完成您所描述的操作。
const INPUT_CHANGE = "INPUT_CHANGE" as const;
const INPUT_BLUR = "INPUT_BLUR" as const;
type InputReducerAction =
| { type: typeof INPUT_CHANGE; value: string; isValid: boolean }
| { type: typeof INPUT_BLUR };
const changeAction: InputReducerAction = {
type: INPUT_CHANGE, value: '', isValid: false
};
const blurAction: InputReducerAction = {
type: INPUT_BLUR
};
问题是JavaScript变量只会在运行时赋值,而TypeScript需要在编译时知道它的值。使用const断言是通知编译器它们的值不应该改变的一种方式。当您获得typeof
变量时,使用文字值而不是通常分配给变量的通用string
类型。