Допустим, есть такой тип:
type MyType = {
foo: string;
bar?: string;
};
и функция
function foo(): MyType {
...
}
При вызове foo()
возвращаемый объект может содержать или не содержать bar
. Но предположим, что в некоторых случаях мы знаем, что определено, например, потому что некоторый набор входных параметров гарантирует, или, возможно, потому, что мы знаем, что определенное состояние выполнено, et c.
Как лучше всего написать такой вызов?
Я знаю, что могу
function baz(): {foo: string; bar: string;} {
const result = foo();
const foo = result.foo;
const bar = result.bar!;
return {foo, bar};
}
Но мне действительно не нужно объявлять каждое свойство таким образом.
Я мог бы немного уточнить это до:
const result = foo();
const bar = result.bar!;
return {...result, bar};
Тем не менее, это меня не очень радует. Я ненавижу невозможность использовать деструктуризацию, и мне кажется, что невозможно утверждать, что свойство определено во время деструктуризации, поэтому я не могу этого сделать:
const {bar!} = result;
Я также пробовал это:
type DefinitelyBar = MyType & {bar: string}
или, возможно, даже
type DefinitelyBar = MyType & Required<Pick<MyType, 'bar'>>;
или, динамически:
type DefinitelyBar = typeof result & Required<Pick<MyType, 'bar'>>;
... и return foo() as DefinitelyBar
.
Но я бы предпочел не необходимо определить псевдоним отдельного типа, а вместо этого просто преобразовать возвращаемое значение в возвращаемое значение, определенное встроенной функцией baz.
Обратите внимание, что я не хочу использовать Required<MyType>
, поскольку могут быть другие необязательные недвижимость в MyType
. Это просто bar
, о котором я утверждаю.
Я также пробовал использовать стандарт assert(result.bar != null)
, чтобы увидеть, сработало ли TS, что после этой строки bar
не может быть undefined
, но нет.
Есть ли быстрое (однострочное sh?) Решение для «вызова foo
, утверждения, что bar
IS определено в возвращенном объекте MyType
, и передать его как тип. где bar
обязательно "?