如何正确推断索引签名?
How to infer index signatures correctly?
似乎无法将输入 arg 推断为通用索引签名(或者我完全遗漏了一些东西)。
如何推断 return 类型并正确验证输入?
interface Styles {
contentAlign?: string;
zIndex?: number;
}
function createTheme<S extends { [key: string]: Styles }>(theme: S) {
return theme;
}
// this works, foo is marked as invalid
const style: Styles = {
zIndex: 1,
foo: 'bar', // <-- invalid
};
// once I try to use the Styles as index signature it allows other properties
const t = createTheme({
Button: {
zIndex: 1,
foo: 'bar', // <-- valid??
},
});
我希望 Type { foo: "bar" } is not assignable to type Styles
,但它似乎是一个有效的输入
S extends { [key: string]: Styles }
意味着 S
可以是 { [key: string]: Styles }
的子类型。但这也意味着 S
的任何 属性 也可以是 Styles
的子类型,因此这意味着任何给定的键实际上可以具有比 [=15= 中指定的属性更多的属性].
通常在 OOP 中,允许在需要基类型的地方分配子类型,Typescript 仅在对象文字直接分配给特定类型时执行额外的 属性 检查。分配给泛型类型参数时,编译器不会执行过多的 属性 检查,因为它假定您要允许子类型(毕竟 S extends {...}
读取任何类型 S
扩展 {...}
).
在你的情况下,因为你想允许任何键,但你实际上不想禁用对 Styles
的多余 属性 检查,我会使用对象的键作为类型参数而不是整个对象:
interface Styles {
contentAlign?: string;
zIndex?: number;
}
function createTheme<K extends PropertyKey>(theme: Record<K, Styles>) {
return theme;
}
// this works, foo is marked as invalid
const style: Styles = {
zIndex: 1,
foo: 'bar', // <-- invalid
};
// once I try to use the Styles as index signature it allows other properties
const t = createTheme({
Button: {
zIndex: 1,
foo: 'bar', // <-- error
},
Header: {
zIndex: 1,
foo: 'bar', // <-- error
},
});
似乎无法将输入 arg 推断为通用索引签名(或者我完全遗漏了一些东西)。
如何推断 return 类型并正确验证输入?
interface Styles {
contentAlign?: string;
zIndex?: number;
}
function createTheme<S extends { [key: string]: Styles }>(theme: S) {
return theme;
}
// this works, foo is marked as invalid
const style: Styles = {
zIndex: 1,
foo: 'bar', // <-- invalid
};
// once I try to use the Styles as index signature it allows other properties
const t = createTheme({
Button: {
zIndex: 1,
foo: 'bar', // <-- valid??
},
});
我希望 Type { foo: "bar" } is not assignable to type Styles
,但它似乎是一个有效的输入
S extends { [key: string]: Styles }
意味着 S
可以是 { [key: string]: Styles }
的子类型。但这也意味着 S
的任何 属性 也可以是 Styles
的子类型,因此这意味着任何给定的键实际上可以具有比 [=15= 中指定的属性更多的属性].
通常在 OOP 中,允许在需要基类型的地方分配子类型,Typescript 仅在对象文字直接分配给特定类型时执行额外的 属性 检查。分配给泛型类型参数时,编译器不会执行过多的 属性 检查,因为它假定您要允许子类型(毕竟 S extends {...}
读取任何类型 S
扩展 {...}
).
在你的情况下,因为你想允许任何键,但你实际上不想禁用对 Styles
的多余 属性 检查,我会使用对象的键作为类型参数而不是整个对象:
interface Styles {
contentAlign?: string;
zIndex?: number;
}
function createTheme<K extends PropertyKey>(theme: Record<K, Styles>) {
return theme;
}
// this works, foo is marked as invalid
const style: Styles = {
zIndex: 1,
foo: 'bar', // <-- invalid
};
// once I try to use the Styles as index signature it allows other properties
const t = createTheme({
Button: {
zIndex: 1,
foo: 'bar', // <-- error
},
Header: {
zIndex: 1,
foo: 'bar', // <-- error
},
});