如何在打字稿查找中匹配键和值



>更新:

感谢@OliverRadini让我到达那里。根据他们的回应,我有一个适用于我的解决方案。我对他们的答案唯一的问题是,我需要在外部键入您传递给函数的内容,但无法找到一种在没有函数的情况下推断键的方法。就我而言,使用实用程序为我们执行此操作是可以的,如下所示:

interface ITest {
n: number;
b: boolean;
}
const f = <K extends keyof ITest>(x: { id: K; params: ITest[K] }) => ({
...x,
_propToConfirmYourUsingTheUtilNeverWriteThisManually: true,
});
type Props = ReturnType<typeof f>;
const a: Props = f({ id: "n", params: 1 }); // no type error
const b: Props = f({ id: "n", params: true }); // Type 'true' is not assignable to type 'number'
const c = f({ id: "b", params: true }); // no type error
const d = f({ id: "b", params: 1 }); // Type 'number' is not assignable to type 'boolean'
// Errors because we didn't add _propToConfirmYourUsingTheUtilNeverWriteThisManually
// This ridiculously named prop should ensure we don't override it without noticing
const z: Props = {
// Property '_propToConfirmYourUsingTheUtilNeverWriteThisManually' is missing in type ...
id: "b",
params: 7,
};
f(a); // no type error
f(b); // no type error
f(c); // no type error
f(d); // no type error

更新:

这种情况可以通过:

const invalidProps1: Props<IdsWithParameters> = {
id: "id1",
params: {
param1: "string",
},
};

除此之外的代码,其他属性不是问题。但是为了使这个组件函数能够成为通用的并且接受任何 idIdsWithParameters我们不能像@oliverradini回复中那样像Props<'id1'>那样显式指定键。但是他们的帮助使我接近了这个目标,但仍然没有完全实现。

interface Props<K extends keyof IdsWithParameters> {
id: K;
params: IdsWithParameters[K];
}
// Somehow want Props to know what is being used as the id and infer 
// the correct params type
function Text(props: Props) {
const text = intlFunctionThatGetsTheTranslatedText(props.id, props.params);
return <>{text}</>
}

原文:

我正在构建一个库,我需要允许人们创建一个对象(IdsWithParameters 接口(,指定允许的键和允许与每个特定键一起使用的类型化参数。在不同的地方,他们将希望指定一个对象,该对象具有与 IdsWithParameters 实例中的 1 个特定键/值对匹配的idparams(Props 接口(。

我可以使用查找到达一个点,您必须将有效的键和参数传递给 Props 实例。但是无法弄清楚如何将参数限制为与给定键/ID 匹配的参数。

interface IdsWithParameters {
id1: {};
id2: {
param1: string;
};
id3: {
param2: boolean;
param3: number;
};
}
interface Props<I extends IdsWithParameters> {
id: keyof I;
params: I[keyof I];
}
// This works as expected
const validProps1: Props<IdsWithParameters> = {
id: "id1",
params: {},
};
// This works as expected
const validProps2: Props<IdsWithParameters> = {
id: "id2",
params: {
param1: "string",
},
};
const invalidProps1: Props<IdsWithParameters> = {
id: "id1",
// Want this to error, saying that params should be {} but it passes
params: {
param1: "string",
},
};
const invalidProps2: Props<IdsWithParameters> = {
id: "id2",
// Want this to error, saying that params should be { param1: string; } but it passes
params: {},
};

我觉得我已经看了太久了,要么有一个简单的方法,要么有一个更好的解决方案,我再也看不到它了。对于上下文,我正在构建一个用于处理 React 包中可翻译内容字符串的包。所以它可以像这样使用:

// IdsWithParameters in above example
interface ContentStringsWithAcceptableParameters {
"errors.404.title": {},
"errors.404.content": {
pageUrl: string;
},
"errors.retryAttemptsLeft": {
attemptsLeft: number;
}
}
interface Props<I extends ContentStringsWithAcceptableParameters> {
id: keyof I;
params: I[keyof I];
}
// The react component we'll be using
function Text(props: Props<ContentStringsWithAcceptableParameters>) {
const text = intlFunctionThatGetsTheTranslatedText(props.id, props.params);
return <>{text}</>
}

我认为如果我们稍微简化一下示例,我们可以理解我们想要做什么:

interface ITest {
n: number;
b: boolean;
}
const f = <K extends keyof ITest>(
x: {
id: K,
params: ITest[K],
},
) => true;
f({ id: 'n', params: 1 });    // no type error
f({ id: 'n', params: true }); // Type 'true' is not assignable to type 'number'
f({ id: 'b', params: true }); // no type error
f({ id: 'b', params: 1 });    // Type 'number' is not assignable to type 'boolean'

我们可以指定一些泛型(K在上面的例子中(扩展了该类型的键。然后,我们可以使用该键来获取我们要查找的类型。

最新更新