我有接口,想用这个接口的键来打字。
示例
interface Test {
a: string;
b: string;
c: string;
d: string | undefined;
e: string | undefined;
}
我的新类型可以在上面的键中有一个属性。我的写作方式如下
type MyNewType<T> = {
[key in keyof T]: T[key];
};
我使用这种类型作为MyNewType<Test>
,但是遇到了错误。
类型{ a: string;}缺少“MyNewType”类型中的下列属性: b、c、d、e.
如何可选地使用属性?
Clarification
我在React中使用减缩器,并调用dispatch
函数,它接受动作创建者作为参数。Test
类型是状态类型,MyNewType<Test>
类型是有效负载类型。操作创建者接受有效负载,并且有效负载可以变成{ a: 'a'}
、{ b: 'b' }
或{ d: undefined }
。但是,error说,有效载荷必须包含所有属性。
发布于 2020-05-28 09:50:46
如果不需要通用解决方案,可以使用以下方法:
MyNewType = { a: string }
| { b: string }
| { c: string }
| { d: string | undefined }
| { d: string | undefined };
对于泛型类型的T
,我想不出有任何方法可以做到这一点。
但是您可以使用另一种方法:而不是仅仅选择一个键值对,您可以为键和值使用单独的属性,例如:
{
key: "a",
value: "a"
}
这可以以一种通用的方式进行:
type MyNewType<T> = {
key: keyof T;
value: T[keyof T];
}
但是,这并不是非常精确,因为您可以将任何键与任何值组合起来。
另一种办法是:
type MyNewType<T, K extends keyof T> = {
key: K;
value: T[K];
}
Wich按预期工作,但引入一个新的类型参数来表示键类型。例如,您可以将它用作:
function dispatch<K extends keyof Test>(testPayload: MyNewType<Test, K>) {
// do something with payload
}
dispatch({ key: "a", value: "a" }); // OK
dispatch({ key: "a", value: undefined }); // Error, because Test.a cannot be undefined
dispatch({ key: "d", value: undefined }); // OK
dispatch({ key: "x", value: undefined }); // Error, because Test does not have property "x"
编辑
我还尝试了以下方法来创建一个完全按照请求的类型:
type MyNewType<T, K extends keyof T> = {
[key: K]: T[K];
}
但是TypeScript在key
上给出了以下错误
索引签名参数类型必须为“string”或“number”。
发布于 2020-05-28 08:32:29
在可选键后面添加一个?
例如,如果您想使a&b可选
interface Test {
a?: string;
b?: string;
c: string;
d: string | undefined;
e: string | undefined;
}
参考资料:https://www.typescriptlang.org/docs/handbook/interfaces.html#optional-properties
发布于 2021-02-13 00:59:05
我有一个类似的问题,并提出了以下设计。
定义一个接口或类型,该接口包含您想要支持的每个属性,但使它们都是可选的,并且永不输入。您可以使用这些属性中的任何一个,但不能将任何东西分配给它们。
interface BaseType {
a?: never;
b?: never;
c?: never;
d?: never;
e?: never;
}
为每个属性创建一个类型,方法是省略base属性并用您想要的类型替换它,但是现在它不再是可选的了。
type AType = Omit<BaseType, "a"> & { "a": string };
type BType = Omit<BaseType, "b"> & { "b": string };
type CType = Omit<BaseType, "c"> & { "c": string };
type DType = Omit<BaseType, "d"> & { "d": string | undefined };
type EType = Omit<BaseType, "e"> & { "e": string | undefined };
结合所有这些单一属性类型来创建MyNewType
。此类型的任何实例都必须是上述单个类型之一。
type MyNewType = AType | BType | CType | DType | EType;
以下几行编译或触发TypeScript错误:
let testA : MyNewType = { "a": "test" } // A is present, and is a string
let testB : MyNewType = { "b": 1 } // B is present, but cannot be a number
let testD : MyNewType = { "d": undefined } // D is present, and may be undefined
let testMultiple : MyNewType = { "a": "Some String", "b": "Another String" } // Cannot include multiple properties
我还在游乐场中设置了这个选项,这样您就可以看到TypeScript错误了。
https://stackoverflow.com/questions/62060188
复制相似问题