英文:
How can I accomplish type narrowing even if the narrowing logic is extracted elsewhere?
问题
I'm trying to conditionally render a react component TransactionSummary
which requires paymentSetup
to be defined.
Edit: paymentSetup
is a value of type PaymentSetupType
| null
which is required by TransactionSummary
.
I've extracted the conditional logic as follows to keep the code clean.
const canShowTransactionSummary = Boolean(paymentSetup && several_other_conditions);
return (
canShowTransactionSummary &&
<TransactionSummary paymentSetup={paymentSetup} ...non_relevant_props />
)
It is possible for paymentSetup
to be null, and I've excluded this possibility by calculating canShowTransactionSummary
. However, I still see a TS warning -
type 'PaymentSetupType | null' is not assignable to type 'PaymentSetupType'.
Type 'null' is not assignable to type 'PaymentSetupType'.
I can resolve this by either
a. including the conditions directly before TransactionSummary ...
(which I want to avoid in order to keep the code clean) or
b. by using
a type annotation (not a preferred option either)
Is there another way to accomplish this?
Edit: Simplified code for TransactionSummary
is below. Only paymentSetup
is a relevant prop for our discussion.
type PaymentSetupType {
unitCost: number;
// other properties (not important)
}
interface Props {
currency: string;
quantity: number;
paymentSetup: PaymentSetupType;
}
const TransactionSummary = ({
currency,
quantity,
paymentSetup,
}: Props): ReactElement => {
const { i18n } = useTranslation();
return (
<div>
Donating
{getFormatedCurrency(
i18n.language,
currency,
paymentSetup.unitCost * quantity
)} for {quantity} trees
</div>
);
};
英文:
I'm trying to conditionally render a react component TransactionSummary
which requires paymentSetup
to be defined.
Edit: paymentSetup
is a value of type PaymentSetupType
| null
which is required by TransactionSummary
.
I've extracted the conditional logic as follows to keep the code clean.
const canShowTransactionSummary = Boolean(paymentSetup && several_other_conditions);
return (
canShowTransactionSummary &&
<TransactionSummary paymentSetup={paymentSetup} ...non_relevant_props />
)
It is possible for paymentSetup
to be null and I've excluded this possibility by calculating canShowTransactionSummary
. However, I still see a TS warning -
type 'PaymentSetupType | null' is not assignable to type 'PaymentSetupType'.
Type 'null' is not assignable to type 'PaymentSetupType'.
I can resolve this by either
a. including the conditions directly before TransactionSummary ...
(which I want to avoid in order to keep the code clean) or
b. by using
a type annotation (not a preferred option either)
Is there another way to accomplish this?
Edit: Simplified code for TransactionSummary
is below. Only paymentSetup
is a relevant prop for our discussion.
type PaymentSetupType {
unitCost: number;
// other properties (not important)
}
interface Props {
currency: string;
quantity: number;
paymentSetup: PaymentSetupType;
}
const TransactionSummary = ({
currency,
quantity,
paymentSetup,
}: Props): ReactElement => {
const { i18n } = useTranslation();
return (
<div>
Donating
{getFormatedCurrency(
i18n.language,
currency,
paymentSetup.unitCost * quantity
)} for {quantity} trees
</div>
);
};
答案1
得分: 1
以下是翻译好的部分:
"Instead of constructing a Boolean
, an explicit null check will successfully narrow the type:
type PaymentSetupType = {};
const paymentSetup = Math.random() < .5 ? {} : null;
const canShowTransactionSummary = paymentSetup != null;
if (canShowTransactionSummary) {
fn(paymentSetup); // no error
}
function fn(paymentSetup: PaymentSetupType) {}"
"TypeScript jsut doesn't seem to deal well with making inferences based on the result of that Boolean
constructor. Even just a standard truthy check would successfully narrow the type:
if (paymentSetup) {
fn(paymentSetup); // no error
}
On a side note, you mention you're trying to keep the code clean, but neither casting potential null values to Boolean
, nor using short-circuit boolean operators to control program flow are the hallmarks of clean code."
英文:
Instead of constructing a Boolean
, an explicit null check will successfully narrow the type:
type PaymentSetupType = {};
const paymentSetup = Math.random() < .5 ? {} : null;
const canShowTransactionSummary = paymentSetup != null;
if (canShowTransactionSummary) {
fn(paymentSetup); // no error
}
function fn(paymentSetup: PaymentSetupType) {}
TypeScript jsut doesn't seem to deal well with making inferences based on the result of that Boolean
constructor. Even just a standard truthy check would successfully narrow the type:
if (paymentSetup) {
fn(paymentSetup); // no error
}
On a side note, you mention you're trying to keep the code clean, but neither casting potential null values to Boolean
, nor using short-circuit boolean operators to control program flow are the hallmarks of clean code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论