我正在尝试创建一个静态函数,它将键名作为字符串接收并返回一个 lambda,它检查该字段是否包含另一个字符串。到目前为止,我所拥有的是这个(有些混乱的)代码:
type Only<T, K> = {
[P in keyof T as (T[P] extends K ? P : never)]: T[P]
};
export class Functions {
public static stringIncludesMatcherForKey<T>(key: keyof Only<T, string>): (a: T, b: string) => boolean {
const stringifier = (obj: T) => (obj[key as unknown as keyof T] as unknown as string).toLowerCase() || '';
return (obj: T, text: string) => stringifier(obj).includes(text);
}
}
此函数将只接受具有字符串类型的键名。例如,如果您将其与以下界面一起使用:
interface Person {
firstName: string;
lastName: string;
birthDate: Date;
}
class CheckPeople
{
Foo() {
const firstNameMatcher = Functions.stringIncludesMatcherForKey<Person>('firstName'); // Fine
const birthDateMatcher = Functions.stringIncludesMatcherForKey<Person>('birthDate'); // Error
}
}
简而言之,该函数将只接受“firstName”或“lastName”作为键,而其他任何东西都按预期在我的 IDE 中显示错误。
但是,当我运行 ng build 时,它会输出一堆令人困惑的语法错误:
ERROR in src/app/_common/pipeline/Functions.ts:30:19 - error TS1005: ']' expected.
30 [P in keyof T as (T[P] extends K ? P : never)]: T[P]
~~
src/app/_common/pipeline/Functions.ts:30:28 - error TS1005: ',' expected.
30 [P in keyof T as (T[P] extends K ? P : never)]: T[P]
~~~~~~~
src/app/_common/pipeline/Functions.ts:30:50 - error TS1005: ';' expected.
30 [P in keyof T as (T[P] extends K ? P : never)]: T[P]
~
src/app/_common/pipeline/Functions.ts:30:51 - error TS1128: Declaration or statement expected.
30 [P in keyof T as (T[P] extends K ? P : never)]: T[P]
~
src/app/_common/pipeline/Functions.ts:31:1 - error TS1128: Declaration or statement expected.
31 };
我创建了以下StackBlitz,它表明该示例可以正常编译并按预期运行。
这意味着错误来自构建配置的差异,但我不知道在那里寻找什么。