简体   繁体   English

我可以对 Typescript 中的变量进行类型断言,该变量应该对整个块/函数有效吗?

[英]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);
  }
}

Playground link 游乐场链接

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.

相关问题 如何使用新的 shiny typescript 断言 function 来做到这一点? - How can I do this with a new and shiny typescript assertion function? typescript 在这种情况下可以做联合类型断言吗? - can typescript do union type assertion in this case? Typescript:我如何最明确地定义一个可以保存 function 名称或该函数返回类型的变量? - Typescript: how do I most explicitly define a variable that can hold a function name or that function's return type? 是否可以保留变量的类型断言,或者有一个“类型断言块”? - Is it possible to persist type assertion of a variable, or have a "type assertion block"? 是否应该尝试捕获 TypeScript 断言 function? - Should try catch TypeScript assertion function? 在TypeScript中键入Assertion而不指定新变量 - Type Assertion in TypeScript without assigning a new variable Typescript 类型断言,可以是数组或普通类型 - Typescript type assertion for type that can be an array or plain 带有关于索引类型的断言的打字稿泛型函数 - Typescript generic function with assertion about indexed type TypeScript:为什么我不能删除这个类型断言? - TypeScript: why I cannot remove this type assertion? 如何使 TypeScript 解构 function 参数,分配默认值,以及可选的整个 object 类型? - How can I make TypeScript deconstruct function parameter, assign default value, and optional whole object type at same time?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM