[英]Can I do a type assertion for a variable in Typescript that should be valid for a whole block/function?
I have a state variable that is of type null | SOME_TYPE
我有一个
null | SOME_TYPE
类型的状态变量null | SOME_TYPE
null | SOME_TYPE
. null | SOME_TYPE
。 But some functions expect it to be SOME_TYPE
and those functions are 100% sure that the state variable will be SOME_TYPE
when they run.但是有些函数期望它是
SOME_TYPE
并且这些函数在运行时 100% 确定状态变量将是SOME_TYPE
。
Can I type cast/assert a variable that will be valid for a whole function scope?我可以输入强制转换/断言一个对整个函数范围有效的变量吗?
Example:例子:
const [myState,setMyState] = useState<null | SOME_TYPE>(null);
function doSomething() {
// THIS FUNCTION NEEDS myState TO BE SOME_TYPE
// IT'S 100% GUARANTEED THAT WHEN IT RUNS, myState WILL BE SOME_TYPE
// IT WILL ACCESS MULTIPLE PROPERTIES OF MY STATE
console.log(myState.someProp as SOME_TYPE);
console.log(myState.someOther as SOME_TYPE);
console.log(myState.another as SOME_TYPE);
}
Instead of multiple and repetitive type casts, can I do a "block" type assertion (without creating a new variable)?我可以做一个“块”类型断言(而不创建新变量)而不是多次重复的类型转换吗?
Example:例子:
function doSomething() {
// myState as SOME_TYPE
// THE IDEA IS THAT INSIDE THIS WHOLE BLOCK myState IS CONSIDERED TO BE SOME_TYPE
console.log(myState.someProp);
console.log(myState.someOther);
console.log(myState.another);
}
Is there a syntax or a proposal for that?是否有语法或建议?
I believe that new variable is acceptable solution, but your other option is an user-defined type guard .我相信 new 变量是可以接受的解决方案,但您的另一个选择是用户定义的类型 guard 。
Contrary to new variable with cast, the preconditon will be checked in runtime.与使用强制转换的新变量相反,先决条件将在运行时检查。
function isSomeType(x: null | SOME_TYPE): x is SOME_TYPE {
return x !== null;
}
function doSomething() {
if (isSomeType(myState)) {
console.log(myState.stateSomeType);
console.log(myState.someOther);
console.log(myState.another);
}
}
Also, as your type is SOME_TYPE | null
另外,由于您的类型是
SOME_TYPE | null
SOME_TYPE | null
, not null guard will work as well: SOME_TYPE | null
,not null 保护也可以工作:
function doSomething() {
if (myState !== null) {
console.log(myState.stateSomeType);
console.log(myState.someOther);
console.log(myState.another);
}
}
You can do that in multiple ways你可以通过多种方式做到这一点
function doSomething() {
if (!myState) return; // Will return if myState is null
// myState is not null for the rest of the function
// Since it could only be null or SOME_TYPE then it must be SOME_TIME
console.log(myState.someProp);
console.log(myState.someOther);
console.log(myState.another);
}
Another way is create another variable that is cast as SOME_TYPE另一种方法是创建另一个被强制转换为 SOME_TYPE 的变量
function doSomething() {
// This cast is basically telling the compiler "shut up, I know what I am doing"
// It's up to you to ensure the correctness and make sure myState is SOME_TYPE
const myVar = myState as SOME_TYPE;
console.log(myVar.someProp);
console.log(myVar.someOther);
console.log(myVar.another);
}
You can also use a Type guard.您还可以使用类型保护。 When your type is SOME_TYPE|null, you only need to check that myState is truthy or return from function if it is falsy as in the first code snippet above.
当您的类型为 SOME_TYPE|null 时,您只需要检查 myState 是否为真,或者如果它为假,则从函数返回,如上面的第一个代码片段。
If you have myState being of type SOME_TYPE|ANOTHER_TYPE.如果您的 myState 类型为 SOME_TYPE|ANOTHER_TYPE。 A simple truthy check will not be enough.
简单的真实检查是不够的。 You can use a type guard.
您可以使用类型保护。
function isSomeType(val: SOME_TYPE|ANOTHER_TYPE): val is SOME_TYPE {
// do a check here to ensure that val is SOME_TYPE
// For example you can check for the presence of a property that is in SOME_TYPE and not ANOTHER_TYPE
return typeof val === 'object' && typeof ((val as SOME_TYPE).someProp) === 'string';
}
function doSomething() {
// Before the call myState is SOME_TYPE|ANOTHER_TYPE
if (!isSomeType(myState)) return;
// After call myState is SOME_TYPE
console.log(myState.someProp);
console.log(myState.someOther);
console.log(myState.another);
}
Without a new variable, if your object is in the same block-scope of your function, then you can change the signature of your function, like this:如果没有新变量,如果您的对象在您的函数的同一个块范围内,那么您可以更改您的函数的签名,如下所示:
const instance = {
someProp: 5,
someOther: true,
another: 'test'
};
doSomething(instance);
function doSomething(arg1: { [key in keyof typeof instance]: SOME_TYPE }) {
// your code here
}
If you use a new variable, you can cast to a type with the same keys as your object:如果使用新变量,则可以转换为与对象具有相同键的类型:
const instance = {
someProp: 5,
someOther: true,
another: 'test'
};
interface SOME_TYPE {
// your type definition
};
const supportVariable = instance as { [key in keyof typeof instance]: SOME_TYPE };
Now every property is set to SOME_TYPE现在每个属性都设置为 SOME_TYPE
console.log(myState.someProp); // No need to use as SOME_TYPE
console.log(myState.someOther); // No need to use as SOME_TYPE
console.log(myState.another); // No need to use as SOME_TYPE
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.