首页 > 解决方案 > 我可以从通用参数推断枚举值吗?

问题描述

我想要的是

我想要一个通用的钩子,为特定的预先存在的属性创建 getter/setter。我的理想实现如下所示:

const [getTitle, setTitle] = useUpdateState("title", "<defaultTitle>");
const [getAge, setAge] = useUpdateState("age", 44);
const [getErr, setErr] = useUpdateState("age", "44"); // Must error, as my types (defined elsewhere) state "age" must be number

选择:

const [getTitle, setTitle] = useUpdateState<TitleUpdate>("Mr");
const [getAge, setAge] = useUpdateState<AgeUpdate>(44);
const [getErr, setErr] = useUpdateState<AgeUpdate>("44"); // Must error

我有的

但是我当前的实现 要求我传入一个类型 AND 属性,以确保defaultValue' 的类型是正确的。


const [getTitle, setTitle] = useUpdateState<TitleUpdate>(Properties.title, "Mr");
const [getAge, setAge] = useUpdateState<AgeUpdate>(Properties.age, 44);
const [getErr, setErr] = useUpdateState<AgeUpdate>(Properties.age, "44"); // Must Error!

感觉就像两种类型,property应该是不必要的。

这是我到目前为止的实现(TypeScriptPlaygroud

enum Properties {
    title = 'title',
    age = 'age',
};
type TitleUpdate = { property: Properties.title, value: string };
type AgeUpdate = { property: Properties.age, value: number };

type Update = TitleUpdate | AgeUpdate;

let state: {
    [Properties.title]: TitleUpdate['value'],
    [Properties.age]: AgeUpdate['value'],
} = {
    [Properties.title]: '',
    [Properties.age]: 0,
}

const useUpdateState = <U extends Update>(property: Properties, defaultValue: U['value']) => {
    // const property = Properties[keyof U]; // <- Want to infer this from U
    const getter = (): U['value'] => state[property];
    const setter = (value: U['value']): void => {
        state = { ...state, ...{ [property]: value } }
    };
    setter(defaultValue);
return [getter, setter];
}

标签: typescript

解决方案


定义状态形状会更容易一些,然后将钩子限制为仅接受具有相应有效值的有效状态键:

type State = { [Properties.title]: string, [Properties.age]: number };

const useUpdateState = <P extends keyof State>(property: P, defaultValue: State[P]) => {
// ...

操场


推荐阅读