كيف يمكنك تعيين صراحة خاصية جديدة على 'نافذة' في تيبسكريبت?

StackOverflow https://stackoverflow.com//questions/12709074

  •  13-12-2019
  •  | 
  •  

سؤال

أقوم بإعداد مساحات أسماء عامة للكائنات الخاصة بي عن طريق تعيين خاصية بشكل صريح على window.

window.MyNamespace = window.MyNamespace || {};

تسطير تيبسكريبت MyNamespace ويشكو من أن:

الخاصية 'مينامسباس' غير موجود على قيمة نوع'نافذة' أي"

يمكنني جعل الكود يعمل بالإعلان MyNamespace كما متغير المحيطة وإسقاط window الصراحة لكنني لا أريد أن أفعل ذلك.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

كيف يمكنني الاحتفاظ بها window هناك وجعل تيبسكريبت سعيدة?

كملاحظة جانبية أجد أنه من المضحك بشكل خاص أن الكتابة المطبوعة تشكو لأنها تخبرني بذلك window هو من النوع any والتي بالتأكيد يمكن أن تحتوي على أي شيء.

هل كانت مفيدة؟

المحلول

وجدت الإجابة فقط على هذا في إجابة سؤال آخر Stackoverflow .

giveacodicetagpre.

أساسا تحتاج إلى تمديد واجهة GransoDicetagCode الموجودة لإخبارها عن الخاصية الجديدة.

نصائح أخرى

للحفاظ على ديناميكية، فقط استخدم:

giveacodicetagpre.

اعتبارا من bydingcript ^ 3.4.3 هذا الحل لم يعد يعمل

أو ...

يمكنك فقط الكتابة:

giveacodicetagpre.

وعدم الحصول على خطأ في الترجمة ويعمل نفس الشيء مثل كتابة window.MyNamespace

باستخدام TSX؟لم تكن أي من الإجابات الأخرى تعمل من أجلي.

إليك ما فعلته:

giveacodicetagpre.

الجواب المقبول هو ما اعتدت استخدامه ، ولكن مع تيبسكريبت 0.9.* لم يعد يعمل.التعريف الجديد لل Window يبدو أن الواجهة تحل محل التعريف المدمج تماما ، بدلا من زيادته.

لقد اتخذت للقيام بذلك بدلا من ذلك:

interface MyWindow extends Window {
    myFunction(): void;
}

declare var window: MyWindow;

تحديث: مع تيبسكريبت 0.9.5 الإجابة المقبولة تعمل مرة أخرى.

global هي "الشر" :)، أعتقد أن أفضل طريقة لتصل إلى إمكانية النقل هي:

أولا تقوم بتصدير الواجهة: (على سبيل المثال :./custom.window.ts)

giveacodicetagpre.

ثانية يمكنك استيراد

giveacodicetagpre.

البراق الثالث من الناحية العالمية VAR مع customwindow

giveacodicetagpre.

بهذه الطريقة، ليس لديك أيضا خط أحمر أيضا في IDE مختلفة إذا كنت تستخدم سمات موجودة كائن النافذة، لذلك في النهاية، حاول:

giveacodicetagpre.

تم اختبارها مع Disscript 2.4.x والأحدث!

إذا كنت بحاجة إلى تمديد window كائن مع نوع مخصص يتطلب استخدام import يمكنك استخدام الطريقة التالية:

نافذة.د. تس

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

انظر 'التعزيز العالمي' في قسم 'دمج الإعلان' من الدليل: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

أنا لست بحاجة إلى القيام بذلك في كثير من الأحيان ، وكانت الحالة الوحيدة التي كان لي عند استخدام ريدوكس ديفتولس مع الوسيطة.

أنا ببساطة فعلت:

const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

أو يمكنك أن تفعل:

let myWindow = window as any;

ثم myWindow.myProp = 'my value';

لأولئك الذين يستخدمون cli الزاوي واضح:

src / polyfnfoles.ts

giveacodicetagpre.

my-custom-utils.ts

giveacodicetagpre.

إذا كنت تستخدم Intellij، فأنت بحاجة أيضا لتغيير الإعداد التالي في IDE قبل التقاط PolyFls الجديد الخاص بك:

giveacodicetagpre.

معظم إجابات أخرى ليست مثالية.

  • بعض منهم فقط لقمع نوع الاستدلال على المحل.
  • بعض من الآخرين فقط يهتم العالمي المتغير كما المجرد ، ولكن ليس واجهة/فئة

أنا أيضا واجهت نفس المشكلة في هذا الصباح.حاولت الكثير من "الحلول" على ذلك ، ولكن أيا منها لا تنتج أي نوع الخطأ تماما وتمكين اثار نوع القفز في IDE(webstorm أو vscode).

وأخيرا ، من هنا

https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512

, أجد حل معقول إرفاق typings العالمي المتغير الذي يعمل بمثابة واجهة/الدرجة مساحة كل.

المثال أدناه:

// typings.d.ts
declare interface Window {
    myNamespace?: MyNamespace & typeof MyNamespace
}

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

الآن رمز أعلاه يدمج typings من مساحة MyNamespace واجهة MyNamespace في متغير عمومي myNamespace(العقار من النافذة).

بعد العثور على إجابات حولها، أعتقد أن هذه الصفحة قد تكون مفيدة. rel="noreferrer"> https://www.typescriptlang.org/docs/handbook/declaration-Merging.html # تعزز العالم لست متأكدا من تاريخ دمج الإعلان، لكنه يفسر لماذا يمكن أن تعمل ما يلي.

giveacodicetagpre.

إليك كيفية القيام بذلك ، إذا كنت تستخدم مدير تعريف الكتابة المطبوعة!

npm install typings --global

إنشاء typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

تثبيت الكتابة المخصصة الخاصة بك:

typings install file:typings/custom/window.d.ts --save --global

تم ، استخدمه! لن يشكو تيبسكريبت بعد الآن:

window.MyNamespace = window.MyNamespace || {};

إذا كنت تستخدم Cydscript 3.x، فقد تتمكن من حذف جزء الجوهرية في الإجابات الأخرى وبدلا من ذلك فقط استخدام:

giveacodicetagpre.

هذا يعمل معي عند استخدام Lydscript 3.3 و Webpack و Tslint.

depsscript لا يؤدي typecheck على خصائص السلسلة.

giveacodicetagpre.

من الناحية المثالية، يجب تجنب سيناريو المتغير العالمي.يمكنني استخدامه في بعض الأحيان لتصحيح كائن في وحدة التحكم في المتصفح.

كمرجع (هذه هي الإجابة الصحيحة):

داخل أ .d.ts ملف التعريف

type MyGlobalFunctionType = (name: string) => void

إذا كنت تعمل في المتصفح, يمكنك إضافة أعضاء إلى سياق نافذة المتصفح عن طريق إعادة فتح واجهة النافذة:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

نفس الفكرة ل نوديجس:

declare module NodeJS {
  interface Global {
    myGlobalFunction: MyGlobalFunctionType
  }
}

الآن تقوم بتعريف متغير الجذر (الذي سيعيش بالفعل على النافذة أو العالمية)

declare const myGlobalFunction: MyGlobalFunctionType;

ثم في العادية .ts ملف ، ولكن المستوردة كأثر جانبي ، كنت في الواقع تنفيذه:

global/* or window */.myGlobalFunction = function (name: string) {
  console.log("Hey !", name);
};

وأخيرا استخدامه في مكان آخر في مصدر برنامج ، مع أي:

global/* or window */.myGlobalFunction("Kevin");

myGlobalFunction("Kevin");

جعل واجهة مخصصة تمتد النافذة وإضافة الخاصية المخصصة الخاصة بك على أنها اختيارية.

بعد ذلك، دع customwindow التي تستخدم الواجهة المخصصة، ولكن تقدر بقيمة النافذة الأصلية.

عملت مع typeScript@3.1.3.

giveacodicetagpre.

بالنسبة لأولئك الذين يرغبون في تعيين خاصية محسوبة أو ديناميكية على window الكائن ، ستجد أنه غير ممكن مع declare global الطريقة.لتوضيح حالة الاستخدام هذه

window[DynamicObject.key] // Element implicitly has an 'any' type because type Window has no index signature

قد تحاول أن تفعل شيئا من هذا القبيل

declare global {
  interface Window {
    [DyanmicObject.key]: string; // error RIP
  }
}

ما سبق سوف خطأ على الرغم من.هذا لأنه في الكتابة المطبوعة ، لا تلعب الواجهات بشكل جيد مع الخصائص المحسوبة وستؤدي إلى حدوث خطأ مثل

A computed property name in an interface must directly refer to a built-in symbol

للالتفاف على هذا ، يمكنك الذهاب مع اقتراح الصب window إلى <any> لذلك يمكنك القيام به

(window as any)[DynamicObject.key]

كنت أرغب في استخدام هذا في مكتبة الزاوي (6) اليوم واستغرق الأمر بعض الوقت للحصول على هذا العمل كما هو متوقع.

من أجل مكتبتي لاستخدام الإعلانات كان لي لاستخدام d.ts تمديد الملف الذي يعلن الخصائص الجديدة للكائن العمومي.

لذلك في النهاية ، انتهى الملف بشيء مثل:

/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts

بمجرد إنشائها، لا تنس كشفها في public_api.ts.

هذا فعل ذلك من أجلي.نأمل أن يساعد هذا.

تحتاج أولا إلى إعلان كائن النافذة في النطاق الحالي.
لأن تيبسكريبت ترغب في معرفة نوع الكائن.
منذ يتم تعريف كائن نافذة في مكان آخر لا يمكنك إعادة تعريفه.
ولكن يمكنك أن تعلن ذلك على النحو التالي:-

declare var window: any;

لن يؤدي هذا إلى إعادة تعريف كائن النافذة أو لن يقوم بإنشاء متغير آخر بالاسم window.
هذا يعني أن النافذة محددة في مكان آخر وأنت تشير إليها فقط في النطاق الحالي.

ثم يمكنك الرجوع إلى كائن مينامسباس الخاص بك ببساطة عن طريق:-

window.MyNamespace

أو يمكنك تعيين الخاصية الجديدة على window كائن ببساطة عن طريق:-

window.MyNamespace = MyObject

والآن لن يشتكي النص المطبوع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top