我只想允许一种类型的对象作为函数参数。对象键必须以
$
开头,仅包含字母字符,并且其值必须为 Test
类型。在下面的“示例 1”下,我仅设法限制为 string
类型的键。我在网上找到了一个 DFA 生成器,它可以检查字符串是否以 $
开头(“示例 2”)。如何将这两者结合起来,以便强制对象的键以 $
开头?请注意“示例 3”底部的变量 validKey
和 invalidKey
。
// example 1
interface Test {
testProperty: string;
}
interface TestObject {
[key: string]: Test;
}
const testObject: TestObject = {
$prop1: {testProperty: 'test'},
$prop2: {testProperty: 'test2'},
};
// example 2
type Head<StrT extends string> = StrT extends `${infer HeadT}${string}` ? HeadT : never;
type Tail<StrT extends string> = StrT extends `${string}${infer TailT}` ? TailT : never;
interface Dfa {
startState: string;
acceptStates: string;
transitions: Record<string, Record<string, string>>;
}
type AcceptsImpl<DfaT extends Dfa, StateT extends string, InputT extends string> = InputT extends ''
? StateT extends DfaT['acceptStates']
? true
: false
: AcceptsImpl<DfaT, DfaT['transitions'][StateT][Head<InputT>], Tail<InputT>>;
type Accepts<DfaT extends Dfa, InputT extends string> = AcceptsImpl<
DfaT,
DfaT['startState'],
InputT
>;
interface MyDfa {
startState: '0';
acceptStates: '1';
transitions: {
'0': Record<'$', '1'> & Record<string, 'fail'>;
'1': Record<
| 'A'
| 'B'
| 'C'
| 'D'
| 'E'
| 'F'
| 'G'
| 'H'
| 'I'
| 'J'
| 'K'
| 'L'
| 'M'
| 'N'
| 'O'
| 'P'
| 'Q'
| 'R'
| 'S'
| 'T'
| 'U'
| 'V'
| 'W'
| 'X'
| 'Y'
| 'Z'
| 'a'
| 'b'
| 'c'
| 'd'
| 'e'
| 'f'
| 'g'
| 'h'
| 'i'
| 'j'
| 'k'
| 'l'
| 'm'
| 'n'
| 'o'
| 'p'
| 'q'
| 'r'
| 's'
| 't'
| 'u'
| 'v'
| 'w'
| 'x'
| 'y'
| 'z',
'1'
> &
Record<string, 'fail'>;
fail: Record<string, 'fail'>;
};
}
type ValidObjectKey<T extends string> = Accepts<MyDfa, T>;
// example 3
const checkValidObjectKey = <T extends string>(key: T) => {
return key as ValidObjectKey<T>;
};
const validKey = checkValidObjectKey('$valid'); // validKey is of type "true"
const invalidKey = checkValidObjectKey('invalid'); // invalidKey is of type "false"
尝试:
type Test = {
testProperty: string;
}
type TestObject = Record<`$${string}`, Test>;
const config: TestObject = {
$a: { testProperty: 'a' },
$b: { testProperty: 'a' },
};