prosource

타이프스크립트:string | defined' 유형은 string 유형에 할당할 수 없습니다.

probook 2023. 3. 19. 18:21
반응형

타이프스크립트:string | defined' 유형은 string 유형에 할당할 수 없습니다.

인터페이스의 속성을 임의로 하여 그 멤버를 다음과 같은 다른 변수에 할당하는 경우:

interface Person {
  name?: string,
  age?: string,
  gender?: string,
  occupation?: string,
}

function getPerson() {
  let person = <Person>{name:"John"};
  return person;
}

let person: Person = getPerson();
let name1: string = person.name; // <<< Error here 

다음과 같은 오류가 발생합니다.

TS2322: Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.

이 에러를 회피하려면 어떻게 해야 하나요?

이제 사용 사례에 정확히 해당하는 null이 아닌 어설션 연산자를 사용할 수 있습니다.

이는 TypeScript에 대해 Null로 보일 수 있지만 그렇지 않다고 신뢰할 수 있음을 알려줍니다.

let name1:string = person.name!; 
//                            ^ note the exclamation mark here  

좀 늦은 건 알지만 Yannick의 대답 말고는!문자열로 캐스팅하여 TypeScript에 다음과 같이 알립니다.는 이것이 문자열이라고 확신하고, 따라서 그것을 변환한다.

let name1:string = person.name;//<<<Error here 

로.

let name1:string = person.name as string;

이렇게 하면 오류가 사라지지만 만약 문자열이 아닌 경우 런타임 오류가 발생합니다.이 때문에 타입이 일치하고 컴파일 시에 이러한 에러가 발생하지 않도록 하기 위해 TypeScript 를 사용하고 있습니다.

사용한 컴파일 오류를 피하기 위해

let name1:string = person.name || '';

그리고 빈 문자열을 확인합니다.

TypeScript 3.7부터는 nullish mergeing 연산자를 사용할 수 있습니다. ??. 이할 때 으로 "으로 생각할 수

let name1:string = person.name ?? '';

??는 '사용할 수 없다'의 을 할 수 .||하려고 할 때, 이나 숫자 때 할 수 .여기서, , 불란, 불란, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난, 불난 등입니다.||사용할 수 없습니다.

부터는 TypeScript 4를 사용할 수 .??= as " " " 。a ??= b은 ""의 입니다.a = a ?? b;

대로라면 ★★★★★★★★★★★★★★★★★★★★」Person.name로 할 수 "" " " " " "name1 가지 시나리오가 .하다

Person.name.

.!

let name1: string = person.name!;

Person.name가 될 수 있다

이름이 null인 경우 기본값을 지정합니다.

let name1: string = person.name ?? "default name";

이 하기 위한 보다 실제 가 된 은 실제로 '실제로'가 '실제 가동'을 하는 입니다.name 한다면, 여러분은 어떻게 해야 알 수 없습니다.getPerson미래에 바뀔 것이다.

if (!person.name) {
    throw new Error("Unexpected error: Missing name");
}

let name1: string = person.name;

Alternatively, you can type 또는 다음을 입력할 수 있습니다.name1 as ~하듯이string | undefined, , and handle cases of , 및 의 케이스에 대응합니다.undefined더 내려가다.더 그러나, 일반적으로 예상치 못한 오류는 일반적으로 예상치 못한 오류입니다.그러나 일반적으로 예기치 않은 오류는 초기에 처리하는 것이 좋습니다.

또한 명시적 유형 스크립트가 명시되어 있는 시 형 략 적 습 형 론 있 니 도 추 let할 you can type수 by type: also명다유유script을 typelet name1 = person.name 해도 「 」는 막을 수 .name1예를 들어 번호로 재할당되지 않도록 합니다.

다음은 무슨 일이 일어나고 있는지 빠르게 파악할 수 있는 방법입니다.

다음을 수행했을 때:

name? : 문자열

TypeScript에 옵션이라고 말씀하셨습니다.그러나 실행했을 때:

let name1 : string = person.name; //<<<Error here 

넌 선택권을 남기지 않았어정의되지 않은 유형을 반영하는 유니온이 있어야 합니다.

let name1 : string | undefined = person.name; //<<<No error here 

당신의 답변을 사용하여 기본적으로 인터페이스, 클래스 및 오브젝트라는 다음 항목을 스케치할 수 있었습니다.이 방법이 더 간단하다고 생각합니다. 그렇지 않다면 신경 쓰지 마세요.

// Interface
interface iPerson {
    fname? : string,
    age? : number,
    gender? : string,
    occupation? : string,
    get_person?: any
}

// Class Object
class Person implements iPerson {
    fname? : string;
    age? : number;
    gender? : string;
    occupation? : string;
    get_person?: any = function () {
        return this.fname;
    }
}

// Object literal
const person1 : Person = {
    fname : 'Steve',
    age : 8,
    gender : 'Male',
    occupation : 'IT'  
}

const p_name: string | undefined = person1.fname;

// Object instance 
const person2: Person = new Person();
person2.fname = 'Steve';
person2.age = 8;
person2.gender = 'Male';
person2.occupation = 'IT';

// Accessing the object literal (person1) and instance (person2)
console.log('person1 : ', p_name);
console.log('person2 : ', person2.get_person());

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ifpersonname에합니다.name1 allocate , " " " 가 됩니다.undefined.

let name1: string = (person.name) ? person.name : undefined;

해결책 1: 명시적 유형 정의 삭제

★★getPerson Person이름을 붙이면 유추형을 사용할 수 있습니다.

function getPerson(){
  let person = {name:"John"};
  return person;
}

let person = getPerson();

을 하자면person: Person을 사용하다는 알고 있습니다.getPerson 、 [ ]됩니다.namePerson선택권을 되찾는 거죠

해결책 2: 보다 정확한 정의 사용

type Require<T, K extends keyof T> = T & {
  [P in K]-?: T[P]
};

function getPerson() {
  let person = {name:"John"};
  return person;
}

let person: Require<Person, 'name'> = getPerson();
let name1:string = person.name;

해결책 3: 인터페이스 재설계

모든 특성이 선택 사항인 모양은 약한 유형이라고 하며 일반적으로 설계가 잘못되었음을 나타냅니다.만약 우리가name필요한 속성으로 문제가 사라집니다.

interface Person {
  name:string,
  age?:string,
  gender?:string,
  occupation?:string,
}

이렇게 하면 돼!

let name1:string = `${person.name}`;

, '기억해 주세요.name1일 수 .

nullable 속성을 다음과 같이 변경하는 경우:

interface Person {
  name?:string | null,
  age?:string | null,
  gender?:string | null,
  occupation?:string | null,
 }

정의되지 않은 경우 속성 이름 앞에서 물음표(?)를 삭제할 수 있습니다.

.name1은 객체필드의 값을 string MUST string으로 설정됩니다namewitch 값 유형은 옵션 문자열로 설정됩니다(질문 기호 때문에 문자열 또는 정의되지 않을 수 있습니다).꼭 , 이 동작의 .name1음음음같 뭇매하다

let name1: string | undefined = person.name;

괜찮을 거야

.NonNullable다음 중 하나:

type T0 = NonNullable<string | number | undefined>;  // string | number
type T1 = NonNullable<string[] | null | undefined>;  // string[]

문서

경고를 생성하지 않는 특성이 정의되지 않았는지 확인하기 위해 찾은 유일한 솔루션입니다.

type NotUndefined<T, K extends keyof T> = T & Record<K, Exclude<T[K], undefined>>;
function checkIfKeyIsDefined<T, K extends keyof T>(item: T, key: K): item is NotUndefined<T, K> {
    return typeof item === 'object' && item !== null && typeof item[key] !== 'undefined';
}

사용방법:


interface Listing { 
    order?: string
    ...
}
obj = {..., order: 'pizza'} as Listing
if(checkIfKeyIsDefined(item: obj, 'order')) {
    order.toUpperCase() //no undefined warning O.O
}

독창적인 대답

「」를했을 경우<Person>의 캐스팅getPerson경우 TypeScript는 하게 "TypeScript"가 할 수 있을 합니다.name★★★★★★★★★★★★★★★★★★.

그러니 그냥 돌아봐:

interface Person {
  name?: string,
  age?: string,
  gender?: string,
  occupation?: string,
}

function getPerson() {
  let person = <Person>{name: 'John'};
  return person;
}

let person: Person = getPerson();
let name1: string = person.name;

입력처:

interface Person {
  name?: string,
  age?: string,
  gender?: string,
  occupation?: string,
}

function getPerson() {
  let person = {name: 'John'};
  return person;
}

let person = getPerson();
let name1: string = person.name;

이 작업을 수행할 수 없는 경우 @yannick1976에서 제안한 대로 "definite assignment assertion operator"를 사용해야 합니다.

let name1: string = person.name!;

사용할 것 같습니다.Require카롤 마예프스키, 카롤 마예프스키 하나의 은 교집합형(는 교집합형)을입니다.Require)

function getPerson(): Person & {name: string} {
  const person = {name:"John"};
  return person;
}

const person = getPerson();
const name1: string = person.name;

「 」를 사용하는 Require또는 교차로 타입은 typscript 컴파일러를 덮어쓰지 않는 것입니다.

특정 상황에서 발생한 한 가지 일(여기서 질문한 특정 문제와는 관련이 없음)은 파일 내에서 잘못된 유형을 Import하고 있었다는 것입니다.유형은 완전히 동일하지만 다른 속성을 정의하고 있기 때문입니다.

올바른 타입을 Import 하면, 모든 문제가 없어집니다.

저와 같은 상황에 처한 사람에게 도움이 되었으면 합니다.

  @Input()employee!:string ;
announced:boolean=false;
confirmed:boolean=false;
task:string="<topshiriq yo'q>";

  constructor(private taskService:TaskService ) {
    taskService.taskAnnon$.subscribe(
      task => {
        this.task=task;
        this.announced=true;
        this.confirmed=false;
      }
    )
  }

  ngOnInit(): void {
  }
  confirm(){
   this.confirmed=true
   this.taskService.confirimTask(this.employee);
  }
}

같은 문제가 있었어.

「」가 추가되는 것을 알 수 ."strict": true로로 합니다.tsconfig.json

제거했더니 모든 게 잘 풀려요.

편집

이 속성을 변경하면 다음 사항이 발생한다는 것을 경고해야 합니다.

잠재적인 런타임 오류에 대한 경고를 더 이상 받지 않습니다.

PaulG가 지적한 바와 같이!감사합니다:)

"strict": false그게 어떤 영향을 미치는지 완전히 이해해야만!

언급URL : https://stackoverflow.com/questions/54496398/typescript-type-string-undefined-is-not-assignable-to-type-string

반응형