提问人:Patrick 提问时间:11/1/2023 最后编辑:Patrick 更新时间:11/2/2023 访问量:80
将对象为未定义键 T 的数组过滤到类型为 guard 的 T 的数组 // 可以使用不同子类型的约束进行实例化
Filter array with object of undefined keys T with type guard to T's with defined keys // could be instantiated with a different subtype of constraint
问:
目标: 筛选未定义的值类型安全
// Key b can be missing in this type:
type AB_ = { a: string; b?: string | undefined, c?: string };
// Key b can no longer be missing but its value type is unchanged
type AB = { a: string, b: string | undefined, c?: string };
const abs: AB_[] = [{ a: '', b: '' }, { a: '', c: '' }];
const as: AB[] /* Type narrowed! */ = abs.filter(x => filterUndefinedKeys('b', x));
// as === [{ a: '', b: '' }];
我想过滤密钥不存在的所有情况。请注意,密钥仍然可以选择存在。b
c
export function filterUndefinedKeys<
TValue extends { Key?: any },
JValue extends { Key: any },
Key extends string,
>(key: Key, value: TValue): value is JValue {
return key in value
}
但是,我收到一个错误。
TS2677: A type predicate's type must be assignable to its parameter's type.
Type JValue is not assignable to type TValue
JValue is assignable to the constraint of type TValue , but TValue could be instantiated with a different subtype of constraint { Key?: any; }
如何在不使用 的情况下让打字稿识别类型中存在的键?as
示例测试用例:
// Tests types: https://www.totaltypescript.com/how-to-test-your-types
type Expect<T extends true> = T;
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
? 1
: 2
? true
: false;
describe('filterHasNotUndefinedKeys()', () => {
it('filters undefined keys', () => {
// Arrange
type Input = { a: string; b?: string | undefined; c?: string };
type Output = { a: string; b: string | undefined; c?: string };
const input: Input = { a: 'a', b: 'b', c: 'c' };
// Act
const output = [input].filter(filterHasNotUndefinedKeys('b'));
// Assert
type _ = Expect<Equal<Output, typeof output>>;
});
});
答: 暂无答案
评论
value is JValue
in
exactOptionalPropertyTypes
{ Key?: any }
undefined
Required<MaybeB>
HasB
null | undefined
(a.key === undefined) === (key in a)