我想在不使用 T 的情况下获得以下行为:
interface Test<T> {
sameField: string;
test: T
testFunction: (e: T) => void
}
const array: Array<Test</*something something*/_>> = [
{
sameField: "foo",
test: 1,
testFunction: (e) => {
e.toExponential(2) // Should be Valid
e.indexOf('e') // Should be Invalid
}
},
{
sameField: "bar",
test: "baz",
testFunction: (e) => {
e.indexOf('e') // Is Valid
e.toExponential(2) // Should be Invalid
}
}
]
它背后的想法只是告诉 Typescript“让数组元素自己处理它们的输入”的一种方式。 是否只能在 Typescript 中进行?
答案 0 :(得分:1)
TS 无法自行推断出此类数据结构中的 e
参数。
这里有多种选择。
第一
预先定义您的 test
属性:
type Main = {
foo: string;
bar: number;
};
type Validator<T extends keyof Main> = {
test: T;
isValid: (value: Main[T]) => boolean;
};
type Values<T> = T[keyof T]
type MainValidationRule = Values<{
[P in keyof Main]: {
test: P;
isValid: (value: Main[P]) => boolean;
}
}>
const validators: Array<MainValidationRule> = [
{ test: 'foo', isValid: (value/* infered to stirng */) => true },
{ test: 'bar', isValid: (value/* infered to number */) => true }
]
第二
interface Test<T> {
field: string;
test: T
fn: (e: T) => void
}
const builder = <Test, Field>(test: Test, field: Field, fn: (e: Test) => any) => ({
field,
test,
fn
})
const array = [builder(2, 'hello', (e/**infered to number */) => 42)]
Here,在我的博客中,您可以找到有关使用和键入回调的更多信息
还有一种方法可以做到:
interface Foo {
sameField: "foo",
test: 1,
testFunction(e: this['test']): void
}
const x: Foo = {
sameField: "foo",
test: 1,
testFunction(e) {
e.toExponential(2) // ok
e.indexOf('e') // error
}
}
但您可能已经注意到,您应该预先声明您的 sameField
和 test
有更多选择可以做到,但我相信这将是一种开销